<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yoshiki Fujiwara(藤原 善基)@AWS Community Builder</title>
    <description>The latest articles on DEV Community by Yoshiki Fujiwara(藤原 善基)@AWS Community Builder (@yoshikifujiwara).</description>
    <link>https://dev.to/yoshikifujiwara</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1143688%2F2e0886ff-292c-4e8f-a588-bc7629c2321b.jpeg</url>
      <title>DEV Community: Yoshiki Fujiwara(藤原 善基)@AWS Community Builder</title>
      <link>https://dev.to/yoshikifujiwara</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yoshikifujiwara"/>
    <language>en</language>
    <item>
      <title>Governance &amp; Cross-Platform Access: Lake Formation, PII Anonymization, and Multi-Engine Reality for S3 Tables</title>
      <dc:creator>Yoshiki Fujiwara(藤原 善基)@AWS Community Builder</dc:creator>
      <pubDate>Mon, 08 Jun 2026 16:49:37 +0000</pubDate>
      <link>https://dev.to/aws-builders/governance-cross-platform-access-lake-formation-pii-anonymization-and-multi-engine-reality-for-30bf</link>
      <guid>https://dev.to/aws-builders/governance-cross-platform-access-lake-formation-pii-anonymization-and-multi-engine-reality-for-30bf</guid>
      <description>&lt;h2&gt;
  
  
  Previously...
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://dev.to/aws-builders/from-hours-to-seconds-an-ai-powered-metadata-catalog-for-unstructured-data-on-fsx-for-ontap-5f54"&gt;Part 1&lt;/a&gt;, we built the metadata catalog. In &lt;a href="https://dev.to/aws-builders/ai-enrichment-pipeline-from-sample-classification-to-100k-file-metadata-search-with-bedrock-and-1imb"&gt;Part 2&lt;/a&gt;, we added AI classification and vector search. Now we need to answer the hard questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Who can see what?&lt;/strong&gt; (governance)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What about PII?&lt;/strong&gt; (anonymization)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Can Databricks/Snowflake access this?&lt;/strong&gt; (cross-platform)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Lake Formation: Governance on Unstructured Data
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;Unstructured data on NAS storage may be well protected at the file-system layer, but it is often not consistently classified, searchable, or governed from analytics and AI workflows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No unified classification → you may not know what's sensitive across the entire corpus&lt;/li&gt;
&lt;li&gt;File-system permissions exist, but analytics/AI tools can't leverage them for discovery&lt;/li&gt;
&lt;li&gt;Audit trails may exist at the file-system layer, but they are often not unified with analytics and AI query activity&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Solution
&lt;/h3&gt;

&lt;p&gt;With metadata in S3 Tables (Iceberg), Lake Formation provides:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌───────────────────────────────────────────────────┐
│  Lake Formation                                   │
│                                                   │
│  Table-level:  SELECT, DESCRIBE                   │
│  Column exposure: controlled via Athena Views     │
│                   (hide embedding_vector, paths)  │
│  Row filtering: WHERE sensitivity_level = 'public'│
│  Audit:        CloudTrail logs metadata queries   │
└───────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verified: Access Control in Action
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 1: Authorized user queries metadata
  → ✅ SUCCEEDED (3 rows returned)

Step 2: Revoke SELECT permission
  → 🔒 BLOCKED: "Column 'file_name' cannot be resolved
     or requester is not authorized"

Step 3: Restore permission
  → ✅ SUCCEEDED (access restored)

Step 4: CloudTrail audit
  → All queries logged with user identity and timestamp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every query against the metadata table is governed and audited. This gives you &lt;strong&gt;100% metadata query governance coverage&lt;/strong&gt; in this PoC. Raw file access remains governed separately by FSx for ONTAP file-system permissions, S3 Access Point policies, and application-specific access paths.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lake Formation Governance Status
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Table-level SELECT / DESCRIBE&lt;/td&gt;
&lt;td&gt;✅ Verified&lt;/td&gt;
&lt;td&gt;Grant/revoke works correctly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Athena query governance&lt;/td&gt;
&lt;td&gt;✅ Verified&lt;/td&gt;
&lt;td&gt;Unauthorized access blocked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CloudTrail audit logging&lt;/td&gt;
&lt;td&gt;✅ Verified&lt;/td&gt;
&lt;td&gt;All queries logged with user identity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Column-level exclusion (ColumnWildcard)&lt;/td&gt;
&lt;td&gt;⚠️ Failed&lt;/td&gt;
&lt;td&gt;On tested S3 Tables federated catalog path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Row-level filtering / LF-Tags&lt;/td&gt;
&lt;td&gt;📋 Design pattern&lt;/td&gt;
&lt;td&gt;Taxonomy defined, needs validation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Column exposure via Athena Views&lt;/td&gt;
&lt;td&gt;✅ Workaround&lt;/td&gt;
&lt;td&gt;Recommended alternative to column-level grants&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Observed Limitation: Column-Level Grants on This S3 Tables Federated Catalog Path
&lt;/h3&gt;

&lt;p&gt;In this PoC, table-level Lake Formation SELECT grants worked as expected. However, column exclusion grants using &lt;code&gt;ColumnWildcard&lt;/code&gt; with &lt;code&gt;ExcludedColumnNames&lt;/code&gt; returned &lt;code&gt;InvalidInputException: Permissions modification is invalid&lt;/code&gt; against the &lt;code&gt;s3tablescatalog/...&lt;/code&gt; federated catalog path we tested.&lt;/p&gt;

&lt;p&gt;AWS documentation &lt;a href="https://docs.aws.amazon.com/lake-formation/latest/dg/s3-tables-grant-permissions.html" rel="noopener noreferrer"&gt;describes table, column, and row-level permissions&lt;/a&gt; for S3 Tables integrated with Lake Formation. Therefore, treat this as an observed limitation in our specific validation path (CLI command, region, catalog ID, engine version), not a confirmed general product limitation. The exact error and test conditions are recorded in the &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/tree/main/integrations/iceberg-metadata-catalog/verification-evidence" rel="noopener noreferrer"&gt;verification evidence&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workaround&lt;/strong&gt;: Create Athena Views that expose only permitted columns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- View for general users (no embeddings, no PII paths)&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;VIEW&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;public_files&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;file_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;classification&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;confidence_score&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="nv"&gt;"s3tablescatalog/fsxn-metadata-catalog"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;"metadata"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;"unstructured_files"&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;is_deleted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;sensitivity_level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'public'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Apply Lake Formation on the view&lt;/span&gt;
&lt;span class="c1"&gt;-- Users query the view, not the base table&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Governance model choice&lt;/strong&gt;: For simple use cases, table/column-level permissions suffice. For dynamic, attribute-based access (e.g., "only files classified as 'public'"), use LF-Tags. For enterprise SSO integration, combine with IAM Identity Center. For enterprise governance, map &lt;code&gt;sensitivity_level&lt;/code&gt;, &lt;code&gt;path_classification&lt;/code&gt;, &lt;code&gt;tenant_id&lt;/code&gt;, and &lt;code&gt;pii_status&lt;/code&gt; to LF-Tags. See &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/governance/lf-tag-taxonomy.yaml" rel="noopener noreferrer"&gt;&lt;code&gt;governance/lf-tag-taxonomy.yaml&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Untested alternative&lt;/strong&gt;: Registering the S3 Tables table in a standard (non-federated) Glue Catalog may enable column-level permissions. This requires manual Iceberg metadata location configuration and has not been verified.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  PII Detection: English + Japanese
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Challenge
&lt;/h3&gt;

&lt;p&gt;Amazon Comprehend's &lt;code&gt;detect_pii_entities&lt;/code&gt; API supports only English and Spanish. For Japanese PII (names, addresses, My Number), we need a different approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dual-Engine Architecture
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Language&lt;/th&gt;
&lt;th&gt;Engine&lt;/th&gt;
&lt;th&gt;Detectable PII&lt;/th&gt;
&lt;th&gt;Latency&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;English&lt;/td&gt;
&lt;td&gt;Amazon Comprehend&lt;/td&gt;
&lt;td&gt;NAME, EMAIL, PHONE, ADDRESS, SSN, CREDIT_CARD, DATE_TIME&lt;/td&gt;
&lt;td&gt;~200ms&lt;/td&gt;
&lt;td&gt;$0.0001/100 chars&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Japanese&lt;/td&gt;
&lt;td&gt;Bedrock Claude&lt;/td&gt;
&lt;td&gt;氏名, メール, 電話, 住所, マイナンバー, クレジットカード, 生年月日&lt;/td&gt;
&lt;td&gt;~2-5s&lt;/td&gt;
&lt;td&gt;~$0.003/request&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Data privacy note&lt;/strong&gt;: When using Bedrock Claude for PII detection, document text is sent to the Bedrock API. Per &lt;a href="https://aws.amazon.com/bedrock/faqs/" rel="noopener noreferrer"&gt;AWS's data privacy policy&lt;/a&gt;, Bedrock does not store or use your inputs/outputs to train models. For highly sensitive workloads, consider VPC endpoints and AWS PrivateLink for Bedrock access.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Japanese PII Detection (Verified)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Bedrock Claude detects Japanese PII via prompt
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bedrock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-3-haiku-20240307-v1:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Detect all PII in this text. Return JSON array: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;[{{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;begin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:N,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:N}}]&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Text:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;japanese_text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Results on a controlled synthetic sample&lt;/strong&gt; (not real personal data):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PII Type&lt;/th&gt;
&lt;th&gt;Detected Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;NAME&lt;/td&gt;
&lt;td&gt;山田太郎&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EMAIL&lt;/td&gt;
&lt;td&gt;&lt;a href="mailto:taro.yamada@example.co.jp"&gt;taro.yamada@example.co.jp&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PHONE&lt;/td&gt;
&lt;td&gt;090-1234-5678&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ADDRESS&lt;/td&gt;
&lt;td&gt;〒150-0002 東京都渋谷区渋谷1-2-3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MY_NUMBER&lt;/td&gt;
&lt;td&gt;1234 5678 9012&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CREDIT_CARD&lt;/td&gt;
&lt;td&gt;4111-1111-1111-1111&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DATE_OF_BIRTH&lt;/td&gt;
&lt;td&gt;1985年3月15日&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Anonymization Pipeline
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Original document
       │
       ▼
PII Detection (Comprehend or Bedrock)
       │
       ├─ No PII → has_pii = false (no action needed)
       │
       └─ PII found → has_pii = true
                          │
                          ▼
              Redaction: all PII → [REDACTED]
                          │
                          ▼
              Store anonymized version
              anonymization_status = "completed"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Name: Taro Yamada
Email: taro.yamada@example.com
Phone: 090-1234-5678
SSN: 123-45-6789
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Name: [REDACTED]
Email: [REDACTED]
Phone: [REDACTED]
SSN: [REDACTED]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Data Clean Room Pattern
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────┐
│  Restricted Table (full metadata)       │
│  • has_pii, anonymized_path, raw paths  │
│  • Access: Security team only           │
│  • Lake Formation: strict SELECT grant  │
└─────────────────────────────────────────┘

┌─────────────────────────────────────────┐
│  Public Table (anonymized metadata)     │
│  • classification, summary (redacted)   │
│  • No PII, no raw file paths            │
│  • Access: All analysts                 │
│  • Lake Formation: broad SELECT grant   │
└─────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Encryption and Data Residency
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;At rest&lt;/strong&gt;: S3 Tables uses SSE-S3 encryption by default. All metadata is encrypted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In transit&lt;/strong&gt;: All API calls use TLS 1.2+.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data residency&lt;/strong&gt;: Both metadata (S3 Tables) and raw files (FSx for ONTAP) remain in the same AWS region. No cross-border data transfer occurs in the default architecture.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For detailed data sovereignty analysis, see the &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/docs/en/iceberg-metadata-catalog.md#data-sovereignty-encryption-and-audit-retention" rel="noopener noreferrer"&gt;Architecture Document — Data Sovereignty section&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Audit Log Retention
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CloudTrail&lt;/strong&gt;: Default 90-day event history. For long-term retention, create a Trail delivering to S3 (recommended: 1+ year for regulated industries)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lake Formation&lt;/strong&gt;: Data access audit logs are recorded via CloudTrail&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenSearch&lt;/strong&gt;: Access logs can be delivered to CloudWatch Logs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analysis&lt;/strong&gt;: Use CloudTrail Lake (SQL queries) or Athena + S3 (cost-efficient) for audit analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For detailed operational monitoring setup, see the &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/docs/en/iceberg-metadata-catalog.md#operational-monitoring" rel="noopener noreferrer"&gt;Operational Monitoring section&lt;/a&gt; in the architecture document.&lt;/p&gt;

&lt;h2&gt;
  
  
  Path Sensitivity Model
&lt;/h2&gt;

&lt;p&gt;File paths can reveal sensitive context even when file contents are not exposed (e.g., &lt;code&gt;/hr/layoffs/2026/&lt;/code&gt; or &lt;code&gt;/legal/mna/target-company/&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Recommended controls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store &lt;code&gt;raw_path&lt;/code&gt; only in the restricted metadata table&lt;/li&gt;
&lt;li&gt;Expose &lt;code&gt;hashed_path&lt;/code&gt; or &lt;code&gt;anonymized_path&lt;/code&gt; to general users&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;path_classification&lt;/code&gt;: public / internal / restricted / confidential&lt;/li&gt;
&lt;li&gt;Apply Lake Formation grants to curated views, not the base table&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Raw Data Access Boundary
&lt;/h2&gt;

&lt;p&gt;This architecture governs &lt;strong&gt;metadata access&lt;/strong&gt; through S3 Tables and Lake Formation. It does not automatically replace:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ONTAP/NFS/SMB file-system permissions&lt;/li&gt;
&lt;li&gt;S3 Access Point resource policies&lt;/li&gt;
&lt;li&gt;IAM permissions for raw file reads&lt;/li&gt;
&lt;li&gt;Application-level authorization&lt;/li&gt;
&lt;li&gt;Downstream use of presigned URLs or copied files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Treat metadata governance and raw data governance as two linked but separate control planes. Both must be configured for end-to-end security.&lt;/p&gt;

&lt;h3&gt;
  
  
  S3 Access Point Identity Boundary
&lt;/h3&gt;

&lt;p&gt;Each FSx for ONTAP S3 Access Point has an associated file-system identity (&lt;code&gt;OntapFileSystemIdentity&lt;/code&gt; — UNIX UID/GID or Windows domain user). All file access through that AP is authorized as that identity.&lt;/p&gt;

&lt;p&gt;For each access point, document:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IAM principals allowed to use the access point&lt;/li&gt;
&lt;li&gt;Access point policy (allowed S3 actions)&lt;/li&gt;
&lt;li&gt;Associated UNIX or Windows file-system identity&lt;/li&gt;
&lt;li&gt;Allowed volume / prefix scope&lt;/li&gt;
&lt;li&gt;Whether the identity can access files beyond what metadata governance intends&lt;/li&gt;
&lt;li&gt;Audit evidence location&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If the AI enrichment access point uses a broad UNIX identity (e.g., root or a service account with wide read access), metadata-level Lake Formation controls do not prevent raw file reads through that AP. Scope the AP identity to minimum required access.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;See &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/security/s3-access-point-identity-matrix.yaml" rel="noopener noreferrer"&gt;&lt;code&gt;security/s3-access-point-identity-matrix.yaml&lt;/code&gt;&lt;/a&gt; for the template.&lt;/p&gt;

&lt;h3&gt;
  
  
  Permission Identity Strategy
&lt;/h3&gt;

&lt;p&gt;For multiprotocol environments (NFS + SMB + S3 AP):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Record &lt;code&gt;discovery_protocol&lt;/code&gt;: nfs / smb / s3ap&lt;/li&gt;
&lt;li&gt;Record &lt;code&gt;access_point_identity_type&lt;/code&gt;: unix / windows&lt;/li&gt;
&lt;li&gt;Record &lt;code&gt;effective_reader_identity&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Record &lt;code&gt;permission_source&lt;/code&gt;: nfs_mode / ntfs_acl / mixed&lt;/li&gt;
&lt;li&gt;Do not assume metadata visibility implies raw file readability&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Retention and Deletion Semantics
&lt;/h2&gt;

&lt;p&gt;This PoC uses metadata records to represent file discovery and enrichment state. For regulated workloads, define:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Metadata retention period (how long to keep catalog records)&lt;/li&gt;
&lt;li&gt;Raw file retention period (governed by storage policy, not this catalog)&lt;/li&gt;
&lt;li&gt;Anonymized metadata retention period&lt;/li&gt;
&lt;li&gt;Deletion request workflow (who can request, who approves, how it's executed)&lt;/li&gt;
&lt;li&gt;Snapshot expiration impact on deletion (Iceberg time travel may expose deleted metadata until snapshots expire)&lt;/li&gt;
&lt;li&gt;Audit evidence retention (keep deletion evidence longer than the data itself)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: Iceberg time travel is useful for recovery, but it means deleted metadata may still be queryable during the snapshot retention window. Align snapshot expiration with your data deletion SLA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Snowflake-side retention&lt;/strong&gt;: If redacted metadata is synced into Snowflake-managed tables, define Snowflake-side retention, Time Travel (default 1 day, up to 90 days), and Fail-safe (7 days, non-configurable) separately from Iceberg snapshot retention. Deletion from the Snowflake copy does not delete from the Iceberg source, and vice versa.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Approval Evidence Template (for Regulated Industries)
&lt;/h3&gt;

&lt;p&gt;For organizations requiring formal access approval documentation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Approval ID: &amp;lt;unique-id&amp;gt;
Data owner: &amp;lt;name/group&amp;gt;
Security owner: &amp;lt;name/group&amp;gt;
Platform owner: &amp;lt;name/group&amp;gt;
Allowed metadata columns: &amp;lt;columns&amp;gt;
Allowed raw file prefixes: &amp;lt;prefixes&amp;gt;
Allowed operations: metadata query only / raw file read / anonymized export
Review date: &amp;lt;date&amp;gt;
Expiration date: &amp;lt;date&amp;gt;
Evidence location: verification-evidence/&amp;lt;path&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Regulated Workload Readiness
&lt;/h2&gt;

&lt;p&gt;For public sector, healthcare, financial services, and other regulated industries, validate the following before production deployment:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Area&lt;/th&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;Status in this PoC&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Data residency&lt;/td&gt;
&lt;td&gt;Metadata and raw files in same AWS Region&lt;/td&gt;
&lt;td&gt;✅ Single region (ap-northeast-1)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encryption at rest&lt;/td&gt;
&lt;td&gt;S3 Tables: SSE-S3; FSx: at-rest encryption&lt;/td&gt;
&lt;td&gt;✅ Default encryption&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encryption in transit&lt;/td&gt;
&lt;td&gt;TLS 1.2+ for all API calls&lt;/td&gt;
&lt;td&gt;✅ AWS default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Raw data access boundary&lt;/td&gt;
&lt;td&gt;File reads governed by S3 AP policy + ONTAP permissions&lt;/td&gt;
&lt;td&gt;✅ Documented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Metadata access boundary&lt;/td&gt;
&lt;td&gt;Lake Formation table-level + CloudTrail audit&lt;/td&gt;
&lt;td&gt;✅ Verified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI processing data flow&lt;/td&gt;
&lt;td&gt;Content sent to Bedrock API, not stored by provider&lt;/td&gt;
&lt;td&gt;✅ Per AWS data protection policy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PII detection limitations&lt;/td&gt;
&lt;td&gt;English (Comprehend) + Japanese (Claude) only&lt;/td&gt;
&lt;td&gt;⚠️ Other languages not covered&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Human review workflow&lt;/td&gt;
&lt;td&gt;Low-confidence queue defined&lt;/td&gt;
&lt;td&gt;✅ Design documented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audit log retention&lt;/td&gt;
&lt;td&gt;CloudTrail 90-day default; configure Trail for longer&lt;/td&gt;
&lt;td&gt;⚠️ Requires Trail setup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deletion SLA&lt;/td&gt;
&lt;td&gt;Define separately for metadata, raw files, and snapshots&lt;/td&gt;
&lt;td&gt;⚠️ Requires policy definition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Legal/compliance sign-off&lt;/td&gt;
&lt;td&gt;Not in scope for this PoC&lt;/td&gt;
&lt;td&gt;❌ Required before production&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI governance note&lt;/strong&gt;: AI enrichment in this pattern is assistive metadata generation. It does not constitute authoritative regulatory classification. Final classification decisions, data handling approvals, and compliance certifications must be confirmed by data owners, security teams, legal counsel, and compliance officers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Cross-Platform Access: The Current Reality
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Fully Verified ✅
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Access Method&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Athena&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Direct query via Glue federated catalog&lt;/td&gt;
&lt;td&gt;✅ Fully verified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lambda/Python&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PyIceberg SDK&lt;/td&gt;
&lt;td&gt;✅ Fully verified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;EMR Spark&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Glue Iceberg REST (EMR 7.13.0+)&lt;/td&gt;
&lt;td&gt;✅ Fully verified (SELECT, COUNT, time travel)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Snowflake&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Glue Iceberg REST + VENDED_CREDENTIALS&lt;/td&gt;
&lt;td&gt;✅ Fully verified (CREATE TABLE, SELECT, COUNT, DESCRIBE, AUTO_REFRESH)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Snowflake&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;External Stage (FSx S3 AP) + TO_FILE + Cortex AI&lt;/td&gt;
&lt;td&gt;✅ Fully verified&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Expected / Requires Validation ⚠️
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Access Method&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;EMR Trino&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Glue Iceberg REST (EMR 7.13.0+)&lt;/td&gt;
&lt;td&gt;⚠️ Expected (same EMR SigV4 handling as Spark)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Redshift Spectrum&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Same as Athena (Glue catalog)&lt;/td&gt;
&lt;td&gt;⚠️ Expected, not fully validated&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  What Doesn't Work (Yet) ⚠️
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Tested method&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;th&gt;Tested&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Databricks SQL Warehouse&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;CREATE CONNECTION TYPE iceberg_rest&lt;/code&gt; to S3 Tables REST&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CONNECTION_TYPE_NOT_SUPPORTED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2026-05-31&lt;/td&gt;
&lt;td&gt;Observed limitation in this path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Databricks Spark cluster&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Iceberg REST + SigV4 via spark.conf.set / cluster config&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;NO_SUCH_CATALOG_EXCEPTION&lt;/code&gt; (UC blocks external catalog registration)&lt;/td&gt;
&lt;td&gt;2026-06-01&lt;/td&gt;
&lt;td&gt;Confirmed: UC Foreign Catalog required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Databricks Delta Sharing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Delta Sharing server accessing S3 AP-backed storage&lt;/td&gt;
&lt;td&gt;Sharing server uses same UC storage credentials; cannot bypass session policy&lt;/td&gt;
&lt;td&gt;2026-06-01&lt;/td&gt;
&lt;td&gt;Confirmed limitation (not a workaround for S3 AP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Databricks NFS → UC Volume&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NFS mount path as UC External Volume&lt;/td&gt;
&lt;td&gt;Cloud storage URIs only (s3://, abfss://, gs://); NFS/FUSE paths not supported&lt;/td&gt;
&lt;td&gt;2026-06-01&lt;/td&gt;
&lt;td&gt;Confirmed limitation; internal feature request exists&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Snowflake&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;External Iceberg Table with S3 Tables direct REST endpoint&lt;/td&gt;
&lt;td&gt;Not a supported catalog type (use Glue REST instead)&lt;/td&gt;
&lt;td&gt;2026-05-31&lt;/td&gt;
&lt;td&gt;Use Glue REST + VENDED_CREDENTIALS (✅ verified)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Snowflake&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CATALOG INTEGRATION with default ACCESS_DELEGATION_MODE&lt;/td&gt;
&lt;td&gt;Defaults to EXTERNAL_VOLUME_CREDENTIALS which triggers ListObjectsV2 (rejected by S3 Tables)&lt;/td&gt;
&lt;td&gt;2026-06-02&lt;/td&gt;
&lt;td&gt;✅ Resolved: set explicit &lt;code&gt;ACCESS_DELEGATION_MODE = VENDED_CREDENTIALS&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Snowflake&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lake Formation column-level via VENDED_CREDENTIALS&lt;/td&gt;
&lt;td&gt;AllowFullTableExternalDataAccess=false blocks all VENDED_CREDENTIALS access&lt;/td&gt;
&lt;td&gt;2026-06-08&lt;/td&gt;
&lt;td&gt;Use Snowflake Horizon (Row Access Policy / Dynamic Masking) for column governance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Snowflake Open Catalog&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Polaris as Iceberg catalog&lt;/td&gt;
&lt;td&gt;Not tested&lt;/td&gt;
&lt;td&gt;TBD&lt;/td&gt;
&lt;td&gt;Strategic alternative&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Databricks: Three Integration Paths to Validate
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update note (2026-06-09)&lt;/strong&gt;: We revalidated the S3 Tables path after Databricks announced GA for Foreign Iceberg and credential vending (May 28, 2026). Glue Connection creation and credential configuration succeeded, but Unity Catalog External Location validation still failed because S3 Tables internal buckets reject standard S3 API validation (HeadBucket/ListBucket). The S3 Tables path remains blocked in this tested Databricks UC configuration. A new Databricks support case has been submitted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For Databricks business users&lt;/strong&gt;: The value is not only table access. The value is turning previously invisible NAS files into governed metadata assets that can be searched, explained, lineage-tracked, and consumed from Databricks SQL, AI/BI, and dashboards.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this PoC, &lt;code&gt;CREATE CONNECTION TYPE iceberg_rest&lt;/code&gt; to the S3 Tables REST endpoint returned &lt;code&gt;CONNECTION_TYPE_NOT_SUPPORTED&lt;/code&gt; on Databricks SQL Warehouse (tested 2026-05-31). This does not mean Databricks lacks Iceberg REST support — Databricks provides Unity Catalog Iceberg REST endpoints and Foreign Iceberg capabilities that evolve rapidly.&lt;/p&gt;

&lt;h4&gt;
  
  
  Confirmed Limitations (2026-06-01)
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;th&gt;Confirmed by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Spark cluster + Iceberg REST (spark.conf.set / cluster config)&lt;/td&gt;
&lt;td&gt;❌ UC blocks external catalog registration&lt;/td&gt;
&lt;td&gt;Databricks support + our testing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delta Sharing via S3 Access Point&lt;/td&gt;
&lt;td&gt;❌ Sharing server uses same UC storage credentials&lt;/td&gt;
&lt;td&gt;Databricks support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NFS mount path as UC External Volume&lt;/td&gt;
&lt;td&gt;❌ Cloud storage URIs only (s3://, abfss://, gs://)&lt;/td&gt;
&lt;td&gt;Databricks support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DataSync → S3 → UC External Delta Table → Delta Sharing&lt;/td&gt;
&lt;td&gt;✅ Works (Delta format required)&lt;/td&gt;
&lt;td&gt;Databricks support&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Delta Sharing note&lt;/strong&gt;: Delta Sharing is not a workaround for the FSx S3 Access Point session policy limitation in our tested path. The sharing server uses the same UC storage credentials and cannot bypass the session policy that blocks S3 AP ARNs. Note that Databricks has &lt;a href="https://www.databricks.com/blog/announcing-first-class-support-iceberg-format-databricks-delta-sharing" rel="noopener noreferrer"&gt;announced first-class Iceberg format support in Delta Sharing&lt;/a&gt; (Jan 2026), enabling providers to share Iceberg tables via the Iceberg REST Catalog API. This broader capability is not contradicted by our finding — our limitation is specific to S3 AP-backed storage access through UC credentials, not Delta Sharing's format support in general.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NFS Volume note&lt;/strong&gt;: UC External Volumes require cloud storage URIs. An internal feature request (AHA) exists for EFS/NFS access via UC. Until this is implemented, DataSync → S3 → UC External Location remains the only supported path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📢 Databricks users&lt;/strong&gt;: If S3 Tables access from Databricks is important for your workflow, the UC Foreign Catalog for S3 Tables feature is being tracked internally by Databricks (request DB-I-15824). Contact your Databricks account team to express interest and increase prioritization. Snowflake achieved full S3 Tables access via VENDED_CREDENTIALS in June 2026 — the same architectural pattern should be feasible for UC.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Immediate workaround for Databricks&lt;/strong&gt;: Use &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/docs/en/datasync-to-s3-guide.md" rel="noopener noreferrer"&gt;DataSync → S3 → UC External Table&lt;/a&gt; to sync metadata into a standard S3 location accessible by Unity Catalog. This is not zero-copy for the synced metadata, but raw files remain on FSx for ONTAP.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Path 1: Spark cluster + Iceberg REST (SigV4)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Best for technical validation and batch processing. Two endpoint options:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tested 2026-06-01&lt;/strong&gt;: On Databricks with Unity Catalog enabled, external Iceberg catalogs cannot be registered via &lt;code&gt;spark.conf.set&lt;/code&gt; or cluster Spark config. Unity Catalog controls catalog registration exclusively. Both Serverless (&lt;code&gt;CONFIG_NOT_AVAILABLE&lt;/code&gt;) and All-Purpose clusters (&lt;code&gt;NO_SUCH_CATALOG_EXCEPTION&lt;/code&gt;) fail. &lt;strong&gt;Unity Catalog Foreign Catalog (Path 2) is the required approach.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="c"&gt;# Path 1a: Direct S3 Tables REST endpoint (used in this PoC)
&lt;/span&gt;&lt;span class="py"&gt;spark.sql.catalog.s3tables.uri&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;https://s3tables.ap-northeast-1.amazonaws.com/iceberg&lt;/span&gt;
&lt;span class="py"&gt;spark.sql.catalog.s3tables.rest.signing-name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;s3tables&lt;/span&gt;

&lt;span class="c"&gt;# Path 1b: AWS Glue Iceberg REST endpoint (recommended for production + Lake Formation)
&lt;/span&gt;&lt;span class="py"&gt;spark.sql.catalog.s3tables.uri&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;https://glue.ap-northeast-1.amazonaws.com/iceberg&lt;/span&gt;
&lt;span class="py"&gt;spark.sql.catalog.s3tables.rest.signing-name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;glue&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common config for both:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;spark.sql.catalog.s3tables&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;org.apache.iceberg.spark.SparkCatalog&lt;/span&gt;
&lt;span class="py"&gt;spark.sql.catalog.s3tables.catalog-impl&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;org.apache.iceberg.rest.RESTCatalog&lt;/span&gt;
&lt;span class="py"&gt;spark.sql.catalog.s3tables.warehouse&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;arn:aws:s3tables:ap-northeast-1:&amp;lt;ACCOUNT&amp;gt;:bucket/fsxn-metadata-catalog&lt;/span&gt;
&lt;span class="py"&gt;spark.sql.catalog.s3tables.rest.sigv4-enabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;spark.sql.catalog.s3tables.rest.signing-region&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;ap-northeast-1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Path 2: Unity Catalog Foreign Iceberg&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Register external Iceberg tables into Unity Catalog if supported for the target catalog/storage path. Best for Databricks governance, lineage, and discovery. Verify refresh semantics and read/write limitations. Retested for S3 Tables on 2026-06-09: Glue Connection and credentials succeeded, but UC External Location validation failed because S3 Tables internal buckets reject standard S3 API validation. This path remains blocked for the tested S3 Tables configuration.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Documentation/version note&lt;/strong&gt;: Databricks Iceberg capabilities are evolving rapidly. Earlier documentation and our initial validation showed limitations around Foreign Iceberg credential vending and automatic refresh behavior. After the &lt;a href="https://www.databricks.com/blog/unity-catalog-and-next-era-apache-icebergtm" rel="noopener noreferrer"&gt;May 2026 GA announcement&lt;/a&gt;, we revalidated the S3 Tables path on 2026-06-09. Credential configuration progressed further, but the tested path still failed at UC External Location validation against S3 Tables internal storage. Additionally, Databricks supports &lt;a href="https://docs.databricks.com/aws/en/query-federation/hms-federation-glue" rel="noopener noreferrer"&gt;catalog federation with AWS Glue&lt;/a&gt; (Hive Metastore type), which can expose Glue-registered tables in UC. Whether a future Iceberg REST catalog federation path could bypass the S3 Tables internal bucket constraint is an open question.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Refresh semantics&lt;/strong&gt;: If UC Foreign Iceberg works for S3 Tables via Glue REST, define refresh semantics explicitly. Our metadata catalog is append-only (new records added on file events). Analysts should know whether Databricks reads the latest Iceberg snapshot automatically or only after &lt;code&gt;REFRESH FOREIGN TABLE&lt;/code&gt;. Without auto-refresh, Athena and Databricks may show temporarily different results until the next refresh cycle. Plan for a scheduled refresh job or event-driven trigger.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS reference for this path&lt;/strong&gt;: AWS has published &lt;a href="https://aws.amazon.com/blogs/big-data/access-amazon-s3-iceberg-tables-from-databricks-using-aws-glue-iceberg-rest-catalog-in-amazon-sagemaker-lakehouse" rel="noopener noreferrer"&gt;guidance on accessing S3 Iceberg tables from Databricks using the Glue Iceberg REST Catalog&lt;/a&gt;. This validates the architectural direction of B-4/B-5, though S3 Tables-specific compatibility requires separate validation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Path 3: AWS Glue Catalog Federation with Databricks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AWS Glue can federate metadata from Databricks Unity Catalog for Iceberg tables. This is the reverse direction but useful for cross-platform governance patterns.&lt;/p&gt;

&lt;h4&gt;
  
  
  Federation Directionality
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Direction&lt;/th&gt;
&lt;th&gt;Primary governance&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;UC Foreign Catalog / Catalog Federation to Glue&lt;/td&gt;
&lt;td&gt;Databricks reads AWS-managed metadata&lt;/td&gt;
&lt;td&gt;Unity Catalog&lt;/td&gt;
&lt;td&gt;Databricks users querying AWS Iceberg (S3 Tables)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS Glue federation to UC&lt;/td&gt;
&lt;td&gt;AWS reads Databricks-managed metadata&lt;/td&gt;
&lt;td&gt;Lake Formation / Glue&lt;/td&gt;
&lt;td&gt;Athena/EMR/Redshift reading UC Iceberg/UniForm&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AWS reference&lt;/strong&gt;: AWS has published guidance on &lt;a href="https://aws.amazon.com/blogs/big-data/access-amazon-s3-iceberg-tables-from-databricks-using-aws-glue-iceberg-rest-catalog-in-amazon-sagemaker-lakehouse" rel="noopener noreferrer"&gt;accessing S3 Iceberg tables from Databricks using AWS Glue Iceberg REST Catalog&lt;/a&gt;, and on &lt;a href="https://docs.aws.amazon.com/lake-formation/latest/dg/catalog-federation-databricks.html" rel="noopener noreferrer"&gt;federating Databricks Unity Catalog data into AWS Glue Data Catalog&lt;/a&gt;. Both directions are documented.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Iceberg here (not Delta Lake)?&lt;/strong&gt; This architecture uses Iceberg because S3 Tables is Iceberg-native, and the Iceberg REST endpoint enables multi-engine access (Athena, EMR, Snowflake). For Databricks-only environments, Delta Lake on S3 remains the natural choice. This pattern targets &lt;strong&gt;multi-platform&lt;/strong&gt; scenarios.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Databricks UC Audit Logging for External Engines (Confirmed 2026-06-01)
&lt;/h3&gt;

&lt;p&gt;External engine access via the UC Iceberg REST Catalog endpoint is fully auditable:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Audit aspect&lt;/th&gt;
&lt;th&gt;Confirmed behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Metadata requests (listNamespaces, listTables, loadTable)&lt;/td&gt;
&lt;td&gt;✅ Logged in &lt;code&gt;system.access.audit&lt;/code&gt; under &lt;code&gt;uniformIcebergRestCatalog&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vended credential issuance&lt;/td&gt;
&lt;td&gt;✅ Logged as &lt;code&gt;loadTableCredentials&lt;/code&gt; / &lt;code&gt;generateTemporaryTableCredential&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audit fields&lt;/td&gt;
&lt;td&gt;user_identity, source_ip_address, user_agent, event_time, action_name, request_params&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Distinguish external vs internal&lt;/td&gt;
&lt;td&gt;✅ &lt;code&gt;service_name = 'uniformIcebergRestCatalog'&lt;/code&gt; (external) vs &lt;code&gt;'unityCatalog'&lt;/code&gt; (internal)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Databricks audit logs record credential issuance, not individual S3 file reads after credentials are vended. Complement with AWS CloudTrail + S3 access logging for file-level audit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Databricks integration documentation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For UC Foreign Catalog validation steps, see &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/databricks/uc-foreign-iceberg-validation.md" rel="noopener noreferrer"&gt;&lt;code&gt;databricks/uc-foreign-iceberg-validation.md&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;For coexistence planning, see &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/databricks/coexistence-roadmap.md" rel="noopener noreferrer"&gt;&lt;code&gt;databricks/coexistence-roadmap.md&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;For audit investigation, see &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/databricks/audit-correlation-guide.md" rel="noopener noreferrer"&gt;&lt;code&gt;databricks/audit-correlation-guide.md&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Snowflake: S3 Tables via Glue REST + VENDED_CREDENTIALS ✅
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Working Configuration (Verified 2026-06-05)
&lt;/h4&gt;

&lt;p&gt;Snowflake can directly query S3 Tables Iceberg tables via the Glue Iceberg REST endpoint with &lt;code&gt;VENDED_CREDENTIALS&lt;/code&gt;. Here's the complete working setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- 1. Catalog Integration (CRITICAL: explicit ACCESS_DELEGATION_MODE)&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="k"&gt;REPLACE&lt;/span&gt; &lt;span class="k"&gt;CATALOG&lt;/span&gt; &lt;span class="n"&gt;INTEGRATION&lt;/span&gt; &lt;span class="n"&gt;s3tables_glue_rest_int&lt;/span&gt;
  &lt;span class="n"&gt;CATALOG_SOURCE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ICEBERG_REST&lt;/span&gt;
  &lt;span class="n"&gt;TABLE_FORMAT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ICEBERG&lt;/span&gt;
  &lt;span class="n"&gt;CATALOG_NAMESPACE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'metadata'&lt;/span&gt;
  &lt;span class="n"&gt;REST_CONFIG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;CATALOG_URI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'https://glue.ap-northeast-1.amazonaws.com/iceberg'&lt;/span&gt;
    &lt;span class="n"&gt;CATALOG_API_TYPE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AWS_GLUE&lt;/span&gt;
    &lt;span class="k"&gt;CATALOG_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;ACCOUNT_ID&amp;gt;:s3tablescatalog/fsxn-metadata-catalog'&lt;/span&gt;
    &lt;span class="n"&gt;ACCESS_DELEGATION_MODE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;VENDED_CREDENTIALS&lt;/span&gt;  &lt;span class="c1"&gt;-- MUST be explicit&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;REST_AUTHENTICATION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;TYPE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SIGV4&lt;/span&gt;
    &lt;span class="n"&gt;SIGV4_IAM_ROLE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'arn:aws:iam::&amp;lt;ACCOUNT_ID&amp;gt;:role/fsxn-snowflake-verification-role'&lt;/span&gt;
    &lt;span class="n"&gt;SIGV4_SIGNING_REGION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ap-northeast-1'&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;ENABLED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;TRUE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- 2. Schema WITHOUT default EXTERNAL_VOLUME (critical)&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;SCHEMA&lt;/span&gt; &lt;span class="n"&gt;FSXN_LAKEHOUSE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;S3TABLES_VENDED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;USE&lt;/span&gt; &lt;span class="k"&gt;SCHEMA&lt;/span&gt; &lt;span class="n"&gt;FSXN_LAKEHOUSE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;S3TABLES_VENDED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- 3. Table WITHOUT EXTERNAL_VOLUME parameter (critical)&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;ICEBERG&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;s3tables_vended_creds_test&lt;/span&gt;
  &lt;span class="k"&gt;CATALOG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'s3tables_glue_rest_int'&lt;/span&gt;
  &lt;span class="n"&gt;CATALOG_TABLE_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'unstructured_files'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;AWS prerequisites&lt;/strong&gt; (must be completed before Snowflake configuration):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Register S3 Tables resource with Lake Formation (--with-federation is REQUIRED)&lt;/span&gt;
aws lakeformation register-resource &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--resource-arn&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:s3tables:ap-northeast-1:&amp;lt;ACCOUNT_ID&amp;gt;:bucket/fsxn-metadata-catalog"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--role-arn&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::&amp;lt;ACCOUNT_ID&amp;gt;:role/S3TablesRoleForLakeFormation"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--with-federation&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; ap-northeast-1

&lt;span class="c"&gt;# Grant SELECT + DESCRIBE to Snowflake's IAM role (table-level)&lt;/span&gt;
aws lakeformation grant-permissions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--principal&lt;/span&gt; &lt;span class="s1"&gt;'{"DataLakePrincipalIdentifier":"arn:aws:iam::&amp;lt;ACCOUNT_ID&amp;gt;:role/fsxn-snowflake-verification-role"}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--resource&lt;/span&gt; &lt;span class="s1"&gt;'{"Table":{"CatalogId":"&amp;lt;ACCOUNT_ID&amp;gt;:s3tablescatalog/fsxn-metadata-catalog","DatabaseName":"metadata","Name":"unstructured_files"}}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--permissions&lt;/span&gt; SELECT DESCRIBE &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; ap-northeast-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IAM role policy must include: &lt;code&gt;glue:GetTable&lt;/code&gt;, &lt;code&gt;glue:GetDatabase&lt;/code&gt;, &lt;code&gt;glue:GetCatalog&lt;/code&gt;, &lt;code&gt;lakeformation:GetDataAccess&lt;/code&gt;, &lt;code&gt;s3tables:GetTableBucket&lt;/code&gt;, &lt;code&gt;s3tables:GetTable&lt;/code&gt;, &lt;code&gt;s3tables:GetNamespace&lt;/code&gt;, &lt;code&gt;s3tables:GetTableData&lt;/code&gt;, &lt;code&gt;s3tables:GetTableMetadataLocation&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verify integration&lt;/strong&gt; (expected DESCRIBE output after creation):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DESCRIBE&lt;/span&gt; &lt;span class="k"&gt;CATALOG&lt;/span&gt; &lt;span class="n"&gt;INTEGRATION&lt;/span&gt; &lt;span class="n"&gt;s3tables_glue_rest_int&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ENABLED&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CATALOG_SOURCE&lt;/td&gt;
&lt;td&gt;ICEBERG_REST&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TABLE_FORMAT&lt;/td&gt;
&lt;td&gt;ICEBERG&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CATALOG_NAMESPACE&lt;/td&gt;
&lt;td&gt;metadata&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REST_CONFIG&lt;/td&gt;
&lt;td&gt;{CATALOG_URI=&lt;a href="https://glue.ap-northeast-1.amazonaws.com/iceberg" rel="noopener noreferrer"&gt;https://glue.ap-northeast-1.amazonaws.com/iceberg&lt;/a&gt;, ...}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REST_AUTHENTICATION&lt;/td&gt;
&lt;td&gt;{TYPE=SIGV4, SIGV4_IAM_ROLE=arn:aws:iam::&amp;lt;ACCOUNT_ID&amp;gt;:role/..., ...}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API_AWS_IAM_USER_ARN&lt;/td&gt;
&lt;td&gt;arn:aws:iam::465774455528:user/&amp;lt;snowflake-user-id&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API_AWS_EXTERNAL_ID&lt;/td&gt;
&lt;td&gt;&amp;lt;external-id-for-trust-policy&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REFRESH_INTERVAL_SECONDS&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Setup step&lt;/strong&gt;: Copy &lt;code&gt;API_AWS_IAM_USER_ARN&lt;/code&gt; and &lt;code&gt;API_AWS_EXTERNAL_ID&lt;/code&gt; from this output into your IAM role's trust policy to allow Snowflake to assume the role.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Verified Capabilities (2026-06-08)
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;th&gt;Performance&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CREATE ICEBERG TABLE&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;6.5s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SELECT * LIMIT 5&lt;/td&gt;
&lt;td&gt;✅ (5 rows)&lt;/td&gt;
&lt;td&gt;1.9s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;COUNT(*)&lt;/td&gt;
&lt;td&gt;✅ (170 rows)&lt;/td&gt;
&lt;td&gt;66ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DESCRIBE TABLE&lt;/td&gt;
&lt;td&gt;✅ (23 columns)&lt;/td&gt;
&lt;td&gt;69ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ALTER ... SET AUTO_REFRESH = TRUE&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;131ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SHOW ICEBERG TABLES&lt;/td&gt;
&lt;td&gt;✅ (UNMANAGED type)&lt;/td&gt;
&lt;td&gt;567ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time Travel&lt;/td&gt;
&lt;td&gt;✅ (available, snapshot-dependent)&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Screenshots&lt;/strong&gt; (URL bar excluded, S3 Tables internal bucket masked):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6wh3589a4rmafhc3dk6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6wh3589a4rmafhc3dk6.png" alt="COUNT(*) = 170 rows" width="799" height="367"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;COUNT(&lt;/em&gt;) returns 170 rows in 66ms*&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvdpx1lm1mivohqyl107a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvdpx1lm1mivohqyl107a.png" alt="DESCRIBE TABLE — 23 columns" width="800" height="444"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;DESCRIBE TABLE shows all 23 Iceberg columns&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq5g2ntq9m6d2dnlsijjh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq5g2ntq9m6d2dnlsijjh.png" alt="SHOW ICEBERG TABLES — UNMANAGED type" width="800" height="369"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;SHOW ICEBERG TABLES confirms UNMANAGED type with S3TABLES_GLUE_REST catalog&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhm1ipy2r40bh2219zbmy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhm1ipy2r40bh2219zbmy.png" alt="SELECT * LIMIT 5 — data from S3 Tables" width="800" height="413"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;SELECT * LIMIT 5 returns actual file metadata from S3 Tables&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AUTO_REFRESH + Time Travel verification:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2s9dh5apfcekpcneg2fl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2s9dh5apfcekpcneg2fl.png" alt="AUTO_REFRESH: COUNT(*) = 171" width="800" height="481"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;AUTO_REFRESH verified: PyIceberg appended 1 record → Snowflake COUNT(&lt;/em&gt;) automatically updated from 170 to 171 within 30 seconds*&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnto5v44pd1s7thpol7uf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnto5v44pd1s7thpol7uf.png" alt="Time Travel: AT(OFFSET =&gt; -1200) = 170" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Time Travel: querying 20 minutes ago returns 170 (before the append), confirming snapshot history is accessible&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;About FILE_PATH&lt;/strong&gt;: The &lt;code&gt;FILE_PATH&lt;/code&gt; column shows the S3 path used during metadata ingestion (via FSx for ONTAP S3 Access Point). This is the path recorded in the Iceberg metadata catalog — it does not mean the files were copied to S3. The actual files remain on FSx for ONTAP and are accessible via NFS, SMB, or S3 Access Point depending on your application's protocol.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Key Insight: Why Previous Attempts Failed
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;ACCESS_DELEGATION_MODE&lt;/code&gt; defaults to &lt;code&gt;EXTERNAL_VOLUME_CREDENTIALS&lt;/code&gt; when not explicitly specified. In this default mode, Snowflake validates storage access through the External Volume path, which triggers &lt;code&gt;ListObjectsV2&lt;/code&gt; against S3 Tables internal buckets — an operation that returns &lt;code&gt;MethodNotAllowed&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;VENDED_CREDENTIALS&lt;/code&gt; explicit:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Snowflake calls Glue REST &lt;code&gt;loadTable&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Lake Formation (via &lt;code&gt;GetTemporaryGlueTableCredentials&lt;/code&gt;) returns temporary storage credentials in the &lt;code&gt;loadTable&lt;/code&gt; response config map&lt;/li&gt;
&lt;li&gt;Snowflake uses these credentials to access data files directly by exact path&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No &lt;code&gt;ListObjectsV2&lt;/code&gt; is required&lt;/strong&gt; — Snowflake reads files by exact path from Iceberg metadata&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The Glue REST endpoint does not implement the standard Iceberg REST &lt;code&gt;/credentials&lt;/code&gt; endpoint. Credential vending works through Lake Formation's proprietary mechanism embedded in the &lt;code&gt;loadTable&lt;/code&gt; response. This is transparent to Snowflake when configured correctly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Governance Limitation: Lake Formation Column-Level (2026-06-08)
&lt;/h4&gt;

&lt;p&gt;Lake Formation column-level filtering is &lt;strong&gt;NOT enforced&lt;/strong&gt; via the VENDED_CREDENTIALS path:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When &lt;code&gt;AllowFullTableExternalDataAccess = false&lt;/code&gt;, the entire VENDED_CREDENTIALS path is blocked&lt;/li&gt;
&lt;li&gt;Explicit column/table-level grants + &lt;code&gt;ExternalDataFilteringAllowList&lt;/code&gt; do not resolve this&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AllowFullTableExternalDataAccess = true&lt;/code&gt; is required for VENDED_CREDENTIALS to function&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Technical context&lt;/strong&gt;: &lt;code&gt;AllowFullTableExternalDataAccess&lt;/code&gt; controls whether external engines (those using Lake Formation credential vending) can access table data without per-table SELECT grants. When set to &lt;code&gt;false&lt;/code&gt;, fine-grained column/row filtering is the intended enforcement mechanism — but for S3 Tables accessed via VENDED_CREDENTIALS, this currently results in complete access denial rather than filtered access. This may be a service-specific constraint of the S3 Tables federated catalog path, or it may require additional &lt;code&gt;AllowExternalDataFiltering&lt;/code&gt; + &lt;code&gt;ExternalDataFilteringAllowList&lt;/code&gt; configuration that was not effective in our testing. A feature request has been submitted to AWS.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Workaround&lt;/strong&gt;: Use Snowflake Horizon for column-level governance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Row Access Policy: restrict by sensitivity_level&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="k"&gt;REPLACE&lt;/span&gt; &lt;span class="k"&gt;ROW&lt;/span&gt; &lt;span class="k"&gt;ACCESS&lt;/span&gt; &lt;span class="n"&gt;POLICY&lt;/span&gt; &lt;span class="n"&gt;metadata_sensitivity_filter&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sensitivity_level&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;RETURNS&lt;/span&gt; &lt;span class="nb"&gt;BOOLEAN&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;CASE&lt;/span&gt;
      &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;IS_ROLE_IN_SESSION&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SECURITY_ADMIN'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="k"&gt;TRUE&lt;/span&gt;
      &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;sensitivity_level&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'public'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'internal'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="k"&gt;TRUE&lt;/span&gt;
      &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="k"&gt;FALSE&lt;/span&gt;
    &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;s3tables_vended_creds_test&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;ROW&lt;/span&gt; &lt;span class="k"&gt;ACCESS&lt;/span&gt; &lt;span class="n"&gt;POLICY&lt;/span&gt;
  &lt;span class="n"&gt;metadata_sensitivity_filter&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sensitivity_level&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Dynamic Data Masking: hide embedding vectors from non-ML roles&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="k"&gt;REPLACE&lt;/span&gt; &lt;span class="n"&gt;MASKING&lt;/span&gt; &lt;span class="n"&gt;POLICY&lt;/span&gt; &lt;span class="n"&gt;mask_embedding&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="nb"&gt;BINARY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;RETURNS&lt;/span&gt; &lt;span class="nb"&gt;BINARY&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;CASE&lt;/span&gt;
      &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;IS_ROLE_IN_SESSION&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ML_ENGINEER'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;
      &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
    &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;s3tables_vended_creds_test&lt;/span&gt; &lt;span class="k"&gt;MODIFY&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt;
  &lt;span class="n"&gt;embedding_vector&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;MASKING&lt;/span&gt; &lt;span class="n"&gt;POLICY&lt;/span&gt; &lt;span class="n"&gt;mask_embedding&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Snowflake Iceberg Access Modes (Summary)
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Access mode&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Glue REST + VENDED_CREDENTIALS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;S3 Tables direct query&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;✅ VERIFIED&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;External Stage (FSx S3 AP) + TO_FILE&lt;/td&gt;
&lt;td&gt;File AI analysis (Cortex COMPLETE)&lt;/td&gt;
&lt;td&gt;✅ VERIFIED&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Metadata sync to Snowflake table&lt;/td&gt;
&lt;td&gt;BI / Cortex Search / governance&lt;/td&gt;
&lt;td&gt;Available&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Object Store Catalog&lt;/td&gt;
&lt;td&gt;Direct metadata file read&lt;/td&gt;
&lt;td&gt;❌ Blocked (S3 Tables internal bucket)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snowflake Open Catalog (Polaris)&lt;/td&gt;
&lt;td&gt;Alternative Iceberg catalog&lt;/td&gt;
&lt;td&gt;Not tested&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;📖 Investigation History (2026-06-01 to 2026-06-05) — click to expand&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2026-05-31&lt;/strong&gt;: Tested S3 Tables direct REST endpoint as External Iceberg catalog → not a supported catalog type.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2026-06-01&lt;/strong&gt;: Created CATALOG INTEGRATION using ICEBERG_REST + AWS_GLUE + VENDED_CREDENTIALS. DESCRIBE succeeded but CREATE ICEBERG TABLE failed with "Failed to retrieve credentials from the Catalog". Root cause identified: Glue REST does not implement &lt;code&gt;/credentials&lt;/code&gt; endpoint (UnknownOperationException).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2026-06-02&lt;/strong&gt;: AWS Support confirmed Lake Formation uses proprietary mechanism (GetTemporaryGlueTableCredentials) for credential vending, not standard Iceberg REST &lt;code&gt;/credentials&lt;/code&gt;. Snowflake Support confirmed Error 004174 occurs when &lt;code&gt;s3.access-key-id/secret/token&lt;/code&gt; absent from loadTable response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2026-06-02&lt;/strong&gt;: Tested Object Store catalog and EXTERNAL_VOLUME_CREDENTIALS mode — both blocked by S3 Tables internal bucket rejecting ListObjectsV2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2026-06-03&lt;/strong&gt;: Discovered &lt;code&gt;register-resource --with-federation&lt;/code&gt; was missing. After setup, loadTable response included credentials. However, CREATE TABLE still failed at storage validation (ListObjectsV2).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2026-06-05&lt;/strong&gt;: Snowflake Support identified the critical distinction: &lt;code&gt;ACCESS_DELEGATION_MODE&lt;/code&gt; defaults to &lt;code&gt;EXTERNAL_VOLUME_CREDENTIALS&lt;/code&gt;. Explicitly setting &lt;code&gt;VENDED_CREDENTIALS&lt;/code&gt; + schema without External Volume + CREATE TABLE without External Volume parameter → &lt;strong&gt;SUCCESS&lt;/strong&gt;. CREATE TABLE + SELECT both working.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2026-06-08&lt;/strong&gt;: Additional testing confirmed COUNT(*), DESCRIBE, AUTO_REFRESH, SHOW ICEBERG TABLES all working. Lake Formation column-level filtering NOT enforced via this path (AllowFullTableExternalDataAccess=false blocks all access).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;External Stage note&lt;/strong&gt;: Snowflake External Stage against the FSx S3 Access Point alias was verified in this PoC (2026-05-31, ap-northeast-1). &lt;strong&gt;Update (2026-06-02): TO_FILE (Cortex COMPLETE multimodal) also verified working&lt;/strong&gt; — Claude Sonnet 4.5 can directly read files from FSx for ONTAP via S3 AP-backed External Stage. See &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/snowflake/external-stage-fsx-s3ap-validation.md" rel="noopener noreferrer"&gt;&lt;code&gt;snowflake/external-stage-fsx-s3ap-validation.md&lt;/code&gt;&lt;/a&gt; for exact DDL and verified operations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Snowflake Metadata Activation Pattern
&lt;/h3&gt;

&lt;p&gt;If you sync only the metadata into Snowflake (not raw files), you preserve the zero-copy principle for actual data while enabling Snowflake-native use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Governed metadata analytics and executive dashboards&lt;/li&gt;
&lt;li&gt;File inventory and PII coverage reporting&lt;/li&gt;
&lt;li&gt;Cortex Search over redacted summaries (RAG on metadata)&lt;/li&gt;
&lt;li&gt;Snowflake Intelligence / Cortex Analyst style business Q&amp;amp;A&lt;/li&gt;
&lt;li&gt;Row Access Policies and Dynamic Masking on synced metadata&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Horizon Catalog note&lt;/strong&gt;: When metadata reaches Snowflake, Snowflake governance features such as Row Access Policies and Dynamic Masking can be applied to Snowflake-managed access paths. For external engine access via Iceberg REST, validate the exact Open Catalog / Horizon behavior for your target engine and security model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Metadata sync best practice&lt;/strong&gt;: Sync curated latest-record metadata, not the append-only base table, unless analysts explicitly need history. Preserve &lt;code&gt;scan_run_id&lt;/code&gt;, &lt;code&gt;change_type&lt;/code&gt;, and &lt;code&gt;is_deleted&lt;/code&gt; for audit and reconciliation. Use &lt;code&gt;MERGE INTO&lt;/code&gt; keyed by &lt;code&gt;file_id&lt;/code&gt; or &lt;code&gt;path_hash&lt;/code&gt; to make metadata activation idempotent. See &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/snowflake/metadata-sync-example.sql" rel="noopener noreferrer"&gt;&lt;code&gt;snowflake/metadata-sync-example.sql&lt;/code&gt;&lt;/a&gt; for the full pattern.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Governance policy mapping&lt;/strong&gt;: When syncing metadata into Snowflake, map AWS-side fields such as &lt;code&gt;sensitivity_level&lt;/code&gt;, &lt;code&gt;tenant_id&lt;/code&gt;, &lt;code&gt;pii_status&lt;/code&gt;, and &lt;code&gt;path_classification&lt;/code&gt; to Snowflake tags, masking policies, and row access policies. Track policy drift between Lake Formation and Snowflake governance. See &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/snowflake/path-decision-guide.md" rel="noopener noreferrer"&gt;&lt;code&gt;snowflake/path-decision-guide.md&lt;/code&gt;&lt;/a&gt; for the full policy mapping.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Snowflake Cortex Search Activation Pattern
&lt;/h3&gt;

&lt;p&gt;If redacted metadata and summaries are synced into Snowflake, &lt;a href="https://docs.snowflake.com/user-guide/snowflake-cortex/cortex-search/cortex-search-overview" rel="noopener noreferrer"&gt;Cortex Search&lt;/a&gt; can provide Snowflake-native enterprise search and RAG over metadata — without managing embeddings, infrastructure, or search quality tuning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Cortex Search here:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Business users can search approved metadata without operating a separate vector database&lt;/li&gt;
&lt;li&gt;RAG and enterprise search can run over redacted summaries already governed in Snowflake&lt;/li&gt;
&lt;li&gt;Search quality, embedding management, and index refresh are delegated to Snowflake-managed services&lt;/li&gt;
&lt;li&gt;This is best suited for Snowflake-first organizations that want business-facing discovery inside the AI Data Cloud&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use Cortex Search for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Executive metadata search (natural language queries over file inventory)&lt;/li&gt;
&lt;li&gt;File inventory Q&amp;amp;A (powered by LLM + retrieval)&lt;/li&gt;
&lt;li&gt;PII coverage reporting and compliance dashboards&lt;/li&gt;
&lt;li&gt;Governed search over redacted summaries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OpenSearch Serverless NextGen remains the AWS-native serving index for this PoC. Cortex Search is an optional Snowflake-native alternative for organizations that standardize on Snowflake for business discovery.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Role separation&lt;/strong&gt;: S3 Tables / Iceberg remains the metadata source of truth. OpenSearch (AWS path) or Cortex Search (Snowflake path) are serving indexes for search UX. Choose based on your primary platform. Cortex Search operates over redacted summaries and metadata synced into Snowflake, not raw files, unless the customer explicitly chooses to copy/extract document content into Snowflake (which would break the zero-copy raw data principle).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cortex Search scope&lt;/strong&gt;: Cortex Search should operate on redacted metadata and summaries by default. If raw document content is extracted or copied into Snowflake for Cortex use cases, treat that as a separate data movement decision with its own governance, retention, and cost model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Snowflake activation cost drivers&lt;/strong&gt;: Snowflake activation introduces separate cost drivers from the AWS-native catalog: warehouse compute for metadata sync tasks and dashboards, Cortex Search service usage (based on corpus size and query volume), task/stream orchestration for refresh, and small metadata storage. These costs should be modeled separately from the AWS-native catalog cost ($114/month estimate in Part 1 does not include Snowflake-side compute).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retention alignment&lt;/strong&gt;: Confirm Snowflake account edition, table type, and retention settings before promising deletion SLAs. Snowflake Time Travel (1–90 days) and Fail-safe (7 days) operate independently from Iceberg snapshot expiration. Snowflake-side deletion evidence should be retained separately from Iceberg snapshot expiration evidence.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Snowflake Metadata Product Contract
&lt;/h3&gt;

&lt;p&gt;When activating metadata in Snowflake, expose a curated subset as the governed metadata product:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommended curated columns:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Column&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Governance&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;file_id&lt;/td&gt;
&lt;td&gt;Unique identifier&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;business_domain&lt;/td&gt;
&lt;td&gt;Organizational grouping&lt;/td&gt;
&lt;td&gt;Row access policy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;file_type&lt;/td&gt;
&lt;td&gt;File format&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;classification&lt;/td&gt;
&lt;td&gt;AI-generated classification&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sensitivity_level&lt;/td&gt;
&lt;td&gt;Data sensitivity tier&lt;/td&gt;
&lt;td&gt;Snowflake tag + masking policy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pii_status&lt;/td&gt;
&lt;td&gt;PII detection result&lt;/td&gt;
&lt;td&gt;Access policy / dashboard filter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redacted_summary&lt;/td&gt;
&lt;td&gt;AI-generated (PII-free) summary&lt;/td&gt;
&lt;td&gt;Cortex Search source column&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;owner_team&lt;/td&gt;
&lt;td&gt;Business ownership&lt;/td&gt;
&lt;td&gt;Business glossary / stewardship&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;last_seen_at&lt;/td&gt;
&lt;td&gt;Last scan timestamp&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;data_quality_status&lt;/td&gt;
&lt;td&gt;Enrichment quality flag&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Snowflake governance mapping:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sensitivity_level&lt;/code&gt; → Snowflake tag + masking policy&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tenant_id&lt;/code&gt; / &lt;code&gt;business_domain&lt;/code&gt; → row access policy&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pii_status&lt;/code&gt; → access policy / dashboard filter&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;redacted_summary&lt;/code&gt; → Cortex Search source column&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;owner_team&lt;/code&gt; → business glossary / stewardship workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Databricks Metadata Activation Pattern
&lt;/h3&gt;

&lt;p&gt;If UC Foreign Catalog is not yet validated for your S3 Tables path, sync only the redacted metadata into a UC-managed Delta table. This preserves the zero-copy principle for raw files while enabling Databricks-native use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Databricks SQL dashboards and executive reporting&lt;/li&gt;
&lt;li&gt;AI/BI Genie over curated metadata (natural language queries)&lt;/li&gt;
&lt;li&gt;UC lineage and audit on metadata usage&lt;/li&gt;
&lt;li&gt;ML feature generation from file metadata&lt;/li&gt;
&lt;li&gt;Operational reporting on PII coverage and enrichment backlog&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Raw files remain on FSx for ONTAP. Only the small metadata table (~MB scale for 100K files) is synced.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is analogous to the Snowflake metadata activation pattern: it copies only curated metadata, not the original unstructured files. Both patterns preserve the zero-copy principle for raw data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Databricks Raw File Access Decision&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;Recommended path&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Governed metadata analytics only&lt;/td&gt;
&lt;td&gt;UC Foreign Catalog (if validated) or sync metadata to UC Delta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Raw file processing in Databricks&lt;/td&gt;
&lt;td&gt;DataSync → S3 → UC External Volume&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zero-copy raw file access from Databricks&lt;/td&gt;
&lt;td&gt;Not supported in validated paths (NFS mount works but without UC governance)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Business discovery / BI&lt;/td&gt;
&lt;td&gt;Sync redacted metadata to UC Delta table&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If metadata is synced into Databricks for BI, include Databricks SQL / Jobs compute cost in the activation model. This does not affect raw-file zero-copy storage, but it is part of the business-facing analytics cost.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Other Lakehouse Engines to Validate
&lt;/h3&gt;

&lt;p&gt;Beyond Databricks and Snowflake, the most natural validation targets for this metadata catalog are:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Engine&lt;/th&gt;
&lt;th&gt;Access path&lt;/th&gt;
&lt;th&gt;Likely fit&lt;/th&gt;
&lt;th&gt;Validation priority&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Trino / Starburst&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Glue Iceberg REST or S3 Tables REST&lt;/td&gt;
&lt;td&gt;Federated SQL, ad hoc query&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;EMR Spark&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Glue Iceberg REST (native since EMR 7.5.0+)&lt;/td&gt;
&lt;td&gt;Bulk backfill, batch enrichment&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Redshift Spectrum&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Glue catalog (external schema)&lt;/td&gt;
&lt;td&gt;DWH integration, BI&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dremio&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Glue catalog or Iceberg REST&lt;/td&gt;
&lt;td&gt;Query acceleration, BI&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;StarRocks / Doris&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Glue Iceberg REST&lt;/td&gt;
&lt;td&gt;Low-latency serving queries&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Apache Flink&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Glue Iceberg REST&lt;/td&gt;
&lt;td&gt;Streaming metadata updates&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;dbt (via Athena)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;dbt-athena + Iceberg materialization&lt;/td&gt;
&lt;td&gt;Analytics engineering, governed marts&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Apache NiFi&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Iceberg REST or Polaris&lt;/td&gt;
&lt;td&gt;Event-driven ingestion&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These engines should be validated against:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;S3 Tables direct REST vs AWS Glue Iceberg REST&lt;/li&gt;
&lt;li&gt;Read vs write capability&lt;/li&gt;
&lt;li&gt;Lake Formation behavior (credential vending, column/row filtering)&lt;/li&gt;
&lt;li&gt;Snapshot freshness after external writes&lt;/li&gt;
&lt;li&gt;Latest-record view compatibility&lt;/li&gt;
&lt;li&gt;Case-sensitivity and lowercase naming requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key finding from validation (2026-06-08)&lt;/strong&gt;: AWS Glue Iceberg REST supports SigV4-authenticated catalog access. Lake Formation credential vending works through a proprietary mechanism (&lt;code&gt;GetTemporaryGlueTableCredentials&lt;/code&gt;). &lt;strong&gt;Snowflake&lt;/strong&gt; requires explicit &lt;code&gt;ACCESS_DELEGATION_MODE = VENDED_CREDENTIALS&lt;/code&gt; — the default mode fails. Engines that can sign requests with their own IAM credentials (EMR Spark ✅ verified, Trino on EMR expected, PyIceberg ✅ verified) work out of the box. Snowflake also works when configured correctly (✅ verified 2026-06-05). &lt;strong&gt;EMR requirement: 7.13.0+&lt;/strong&gt; (7.5.0 has a credential resolution bug). &lt;strong&gt;Governance note&lt;/strong&gt;: Lake Formation column-level filtering is NOT enforced via the VENDED_CREDENTIALS path for Snowflake.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trino note&lt;/strong&gt;: AWS has published &lt;a href="https://aws.amazon.com/blogs/big-data/" rel="noopener noreferrer"&gt;guidance on querying S3 Tables from Trino using the Iceberg REST endpoint&lt;/a&gt;. Trino's Iceberg connector supports REST catalogs natively, making it one of the most straightforward third-party validation targets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EMR Spark note&lt;/strong&gt;: For large-scale backfill or re-enrichment (100K+ files), Spark on EMR Serverless or EMR on EC2 can be used as an alternative to Lambda/Fargate. Use &lt;a href="https://docs.aws.amazon.com/glue/latest/dg/connect-glu-iceberg-rest.html" rel="noopener noreferrer"&gt;Glue Iceberg REST&lt;/a&gt; for centralized metadata access with Lake Formation governance. &lt;strong&gt;Verified (2026-06-02)&lt;/strong&gt;: EMR Serverless Spark 7.13.0 successfully reads S3 Tables metadata via Glue Iceberg REST — SHOW NAMESPACES, SHOW TABLES, SELECT, COUNT, and snapshot history all work. Requires EMR 7.13.0+ (7.5.0 has a credential resolution bug for S3 Tables warehouse format).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Redshift note&lt;/strong&gt;: Validate separately from Athena — external schema setup, Glue statistics, Lake Formation permissions, and query latency against latest-record views may differ.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For the full compatibility matrix, see &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/lakehouse-tools/tool-compatibility-matrix.yaml" rel="noopener noreferrer"&gt;&lt;code&gt;lakehouse-tools/tool-compatibility-matrix.yaml&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Catalog Authority Rule
&lt;/h3&gt;

&lt;p&gt;For each Iceberg table, define exactly one authoritative catalog for metadata pointer and commit coordination. Do not operate S3 Tables, Polaris, Gravitino, Nessie, and Glue as independent writable catalogs for the same table unless the integration explicitly supports federation without dual writes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    ┌──────────────────────┐
                    │ Authoritative Catalog│
                    │ (ONE per table)      │
                    │ • S3 Tables + Glue   │
                    │   (this PoC)         │
                    └──────────┬───────────┘
                               │
              ┌────────────────┼────────────────┐
              │                │                │
              ▼                ▼                ▼
         Read-only        Read-only        Read-only
         consumers        consumers        consumers
         (Trino,          (Databricks,     (Snowflake,
          Dremio,          UC Foreign       Cortex,
          StarRocks)       Catalog)         Open Catalog)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Split-brain warning&lt;/strong&gt;: If two catalogs independently write to the same Iceberg table, snapshot pointers can diverge, causing data loss or corruption. Federation (one writer, many readers) is safe. Dual-write is not.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The Bigger Picture
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    S3 Tables (Iceberg)
                           │
              ┌────────────┼────────────┐
              │            │            │
              ▼            ▼            ▼
         Athena ✅    Databricks ❌  Snowflake ✅
         EMR Spark ✅  (UC Foreign    (Glue REST +
         PyIceberg ✅   path still    VENDED_CREDENTIALS
                      blocked in     verified 2026-06-05)
                      tested config)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Databricks integration summary&lt;/strong&gt; (confirmed 2026-06-01):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Direct S3 AP access: ❌ (UC session policy)&lt;/li&gt;
&lt;li&gt;NFS mount → UC Volume: ❌ (cloud URI only)&lt;/li&gt;
&lt;li&gt;Delta Sharing via S3 AP: ❌ (same credentials)&lt;/li&gt;
&lt;li&gt;DataSync → S3 → UC: ✅ (supported workaround, not zero-copy for synced data)&lt;/li&gt;
&lt;li&gt;UC Foreign Catalog / Foreign Iceberg via Glue: ❌ Retested 2026-06-09; Glue Connection and credentials succeeded, but UC External Location validation failed against S3 Tables internal storage. Support case submitted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For capability-level details such as read, write, time travel, metadata tables, and governance behavior, see &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/verification-evidence/cross-platform-compatibility.yaml" rel="noopener noreferrer"&gt;&lt;code&gt;verification-evidence/cross-platform-compatibility.yaml&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is a &lt;strong&gt;temporary gap&lt;/strong&gt;. S3 Tables is relatively new (GA Dec 2024), and cross-platform federation is actively being developed. Feature requests have been filed with both platforms. Timeline for native S3 Tables support is unknown, but the Iceberg ecosystem is converging rapidly — Unity Catalog 2.0's native Iceberg support and Snowflake's Open Catalog (Polaris) both point toward broader interoperability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Catalog Decision Guide
&lt;/h3&gt;

&lt;p&gt;In the Iceberg world, the catalog is the system of record for table metadata pointers and atomic operations. Choose based on your primary platform:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Primary platform&lt;/th&gt;
&lt;th&gt;Recommended catalog&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AWS-first / Athena-first&lt;/td&gt;
&lt;td&gt;S3 Tables + Glue/Lake Formation&lt;/td&gt;
&lt;td&gt;Used in this PoC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databricks-first&lt;/td&gt;
&lt;td&gt;Unity Catalog Managed/Foreign Iceberg&lt;/td&gt;
&lt;td&gt;Best for UC governance, lineage, discovery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snowflake-first&lt;/td&gt;
&lt;td&gt;Snowflake Open Catalog (Polaris)&lt;/td&gt;
&lt;td&gt;Best for Snowflake-governed Iceberg interoperability; validate external engine governance behavior&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Neutral / OSS-first&lt;/td&gt;
&lt;td&gt;Apache Polaris or other REST catalog&lt;/td&gt;
&lt;td&gt;Maximum portability&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Dual catalog warning&lt;/strong&gt;: Avoid running two authoritative catalogs for the same Iceberg table. Use Snowflake Open Catalog / Polaris when Snowflake or a neutral REST catalog should be authoritative. Use S3 Tables when AWS-native Athena / Lake Formation / Glue governance is authoritative. If both platforms need access, use federation (one authoritative catalog, others read via REST).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  When to Consider Snowflake Open Catalog / Polaris
&lt;/h4&gt;

&lt;p&gt;Use S3 Tables + Glue/Lake Formation when AWS-native governance is authoritative (this PoC).&lt;/p&gt;

&lt;p&gt;Consider &lt;a href="https://docs.snowflake.com/en/user-guide/polaris-catalog" rel="noopener noreferrer"&gt;Snowflake Open Catalog&lt;/a&gt; / Polaris when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Snowflake should be the primary governance and interoperability plane&lt;/li&gt;
&lt;li&gt;Multiple engines need Iceberg REST access through a neutral catalog&lt;/li&gt;
&lt;li&gt;Snowflake-managed Iceberg or Snowflake-first AI/Data Cloud workflows are the center of gravity&lt;/li&gt;
&lt;li&gt;You want managed Polaris instead of operating your own REST catalog&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This would be a different authoritative-catalog design from the current PoC and should not be mixed as a second writer for the same table.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Databricks-first note&lt;/strong&gt;: For organizations standardizing on Databricks, consider whether the metadata catalog itself should be managed in Unity Catalog as Managed Iceberg or Delta + UniForm, then exposed to AWS engines through &lt;a href="https://docs.aws.amazon.com/lake-formation/latest/dg/catalog-federation-databricks.html" rel="noopener noreferrer"&gt;Glue federation to UC&lt;/a&gt; or the UC Iceberg REST endpoint. Use S3 Tables when AWS-native Athena/Lake Formation is the primary governance path. The choice depends on which governance plane (UC or Lake Formation) is authoritative for your organization.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Format Decision for Databricks Environments
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;th&gt;Tradeoff&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S3 Tables Iceberg&lt;/td&gt;
&lt;td&gt;AWS-first Athena/LF governance&lt;/td&gt;
&lt;td&gt;UC integration pending (Foreign Catalog validation)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UC Managed / Foreign Iceberg&lt;/td&gt;
&lt;td&gt;Databricks-first open format governance&lt;/td&gt;
&lt;td&gt;Validate current feature availability, region support, and limitations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delta + UniForm&lt;/td&gt;
&lt;td&gt;Databricks-native pipelines + Iceberg read compatibility&lt;/td&gt;
&lt;td&gt;Iceberg metadata generated asynchronously; non-Databricks writes constrained&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Metadata sync to Delta&lt;/td&gt;
&lt;td&gt;BI activation in Databricks SQL&lt;/td&gt;
&lt;td&gt;Metadata copy, but raw files remain zero-copy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Summary: What We Built
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Storage&lt;/td&gt;
&lt;td&gt;FSx for ONTAP (files) + S3 Tables (metadata)&lt;/td&gt;
&lt;td&gt;✅ Verified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI&lt;/td&gt;
&lt;td&gt;Bedrock Claude Vision + Titan Embeddings V2&lt;/td&gt;
&lt;td&gt;✅ Verified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search&lt;/td&gt;
&lt;td&gt;OpenSearch Serverless NextGen (scale-to-zero)&lt;/td&gt;
&lt;td&gt;✅ Verified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Governance&lt;/td&gt;
&lt;td&gt;Lake Formation (table-level) + CloudTrail&lt;/td&gt;
&lt;td&gt;✅ Verified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PII&lt;/td&gt;
&lt;td&gt;Comprehend (EN) + Bedrock Claude (JA)&lt;/td&gt;
&lt;td&gt;✅ Verified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-platform&lt;/td&gt;
&lt;td&gt;Athena ✅, EMR Spark ✅, PyIceberg ✅, Snowflake ✅, Databricks ⚠️&lt;/td&gt;
&lt;td&gt;Mostly verified&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The Numbers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;42 seconds&lt;/strong&gt;: Full demo execution time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;$0.07&lt;/strong&gt;: Total demo cost&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Near $0 idle compute/search cost&lt;/strong&gt;: Persistent metadata, logs, and audit trails may still incur small charges&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;$114/month&lt;/strong&gt;: Projected cost at 100K files, 1000 changes/day&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;95%&lt;/strong&gt;: Storage cost reduction vs S3 full copy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0.95&lt;/strong&gt;: AI classification confidence (invoice detection)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;7/7&lt;/strong&gt;: PII entities detected and redacted&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;For regulated workloads, align Iceberg snapshot retention with deletion SLAs and audit evidence retention.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What's Next for This Project
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Monitor support cases&lt;/strong&gt;: Databricks UC Foreign Catalog for S3 Tables — timeline unknown&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production hardening&lt;/strong&gt;: SQS batching, DLQ alerting, reconciliation jobs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-language PII&lt;/strong&gt;: Extend beyond EN/JA to other languages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost optimization&lt;/strong&gt;: Provisioned Throughput for high-volume Bedrock usage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production semantics&lt;/strong&gt;: File identity, latest-record views, index reconciliation, and snapshot retention alignment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ONTAP production hardening&lt;/strong&gt;: S3 Access Point identity matrix, FPolicy event filtering, SnapMirror catalog rebinding, and FSx performance dashboard&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Snowflake governance&lt;/strong&gt;: Implement Horizon Row Access Policies and Dynamic Data Masking for column-level protection (since Lake Formation column-level is not enforced via VENDED_CREDENTIALS)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Get Involved
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;⭐ &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations" rel="noopener noreferrer"&gt;Star the repo&lt;/a&gt; if this was useful&lt;/li&gt;
&lt;li&gt;🐛 &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/issues" rel="noopener noreferrer"&gt;Open an Issue&lt;/a&gt; for questions or suggestions&lt;/li&gt;
&lt;li&gt;🍴 Fork and adapt for your own unstructured data catalog&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;This concludes the 3-part series. All code is at &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/fsxn-lakehouse-integrations&lt;/a&gt;. Questions? Open a GitHub Issue.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Governance disclaimer&lt;/strong&gt;: This article provides governance guidance and architectural patterns. It does not substitute for legal or compliance judgment. Final regulatory determinations should be confirmed with legal and compliance teams.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>aws</category>
      <category>iceberg</category>
      <category>s3tables</category>
      <category>amazonfsxfornetappontap</category>
    </item>
    <item>
      <title>AI Enrichment Pipeline: From Sample Classification to 100K-File Metadata Search with Bedrock and OpenSearch NextGen</title>
      <dc:creator>Yoshiki Fujiwara(藤原 善基)@AWS Community Builder</dc:creator>
      <pubDate>Mon, 08 Jun 2026 16:37:44 +0000</pubDate>
      <link>https://dev.to/aws-builders/ai-enrichment-pipeline-from-sample-classification-to-100k-file-metadata-search-with-bedrock-and-1imb</link>
      <guid>https://dev.to/aws-builders/ai-enrichment-pipeline-from-sample-classification-to-100k-file-metadata-search-with-bedrock-and-1imb</guid>
      <description>&lt;h2&gt;
  
  
  Quick Recap: What We Built in Part 1
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://dev.to/aws-builders/from-hours-to-seconds-an-ai-powered-metadata-catalog-for-unstructured-data-on-fsx-for-ontap-5f54"&gt;Part 1&lt;/a&gt;, we built a metadata catalog on Apache Iceberg (S3 Tables) that makes unstructured files on FSx for ONTAP instantly searchable via Athena SQL — in under 2 seconds, at $5-15/month for 100K files, without bulk-copying raw files.&lt;/p&gt;

&lt;p&gt;But basic metadata (file name, size, type) only gets you so far. &lt;strong&gt;What if you could ask&lt;/strong&gt;: "Find all invoices from Q4" or "Show me files similar to this contract"?&lt;/p&gt;

&lt;p&gt;That requires &lt;strong&gt;AI enrichment&lt;/strong&gt;: automatically classifying files and generating vector embeddings for similarity search.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We're Building
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;File on FSx for ONTAP
       │
       │ S3 Access Point (read)
       ▼
┌─────────────────────────────────────────┐
│  Bedrock Claude Vision                  │
│  "What is this file?"                   │
│  → classification: "invoice"            │
│  → confidence: 0.95                     │
│  → summary: "Invoice #INV-2024-..."     │
└──────────────────┬──────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────┐
│  Titan Embeddings V2                    │
│  "Represent this file as a vector"      │
│  → 1024-dimensional embedding           │
│  → normalized for cosine similarity     │
└──────────────────┬──────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────┐
│  S3 Tables (Iceberg)                    │
│  classification, confidence_score,      │
│  summary, embedding_vector              │
└──────────────────┬──────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────┐
│  OpenSearch Serverless NextGen          │
│  kNN vector search                      │
│  "Find files similar to X"              │
│  Scale-to-zero: $0 when idle            │
└─────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  AI Classification: Bedrock Claude Vision
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;p&gt;For image files (PNG, JPEG, TIFF), we send the file to Claude Vision with a simple prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bedrock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-3-haiku-20240307-v1:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic_version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bedrock-2023-05-31&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_tokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;source&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;base64&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;media_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image/png&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;image_b64&lt;/span&gt;
            &lt;span class="p"&gt;}},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
                &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Classify this image. Respond JSON only: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
                &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;classification&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;confidence_score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:0.X,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;summary&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]}]&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Results (Measured)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Classification&lt;/th&gt;
&lt;th&gt;Confidence&lt;/th&gt;
&lt;th&gt;Latency&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;invoice_sample.png&lt;/td&gt;
&lt;td&gt;Invoice&lt;/td&gt;
&lt;td&gt;0.95&lt;/td&gt;
&lt;td&gt;~3s&lt;/td&gt;
&lt;td&gt;$0.01&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;product_inspection.png&lt;/td&gt;
&lt;td&gt;Pie Chart&lt;/td&gt;
&lt;td&gt;1.0&lt;/td&gt;
&lt;td&gt;~2s&lt;/td&gt;
&lt;td&gt;$0.01&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sensor_dashboard.png&lt;/td&gt;
&lt;td&gt;IoT Sensor Dashboard&lt;/td&gt;
&lt;td&gt;0.9&lt;/td&gt;
&lt;td&gt;~3s&lt;/td&gt;
&lt;td&gt;$0.01&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Key insight&lt;/strong&gt;: In this demo, Claude 3 Haiku classified sample images in ~2-3 seconds at roughly $0.01/image. Production accuracy and cost depend on image size, prompt length, model version, and document type.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Model version note&lt;/strong&gt;: Model ID &lt;code&gt;anthropic.claude-3-haiku-20240307-v1:0&lt;/code&gt; was used at time of testing. Check &lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids.html" rel="noopener noreferrer"&gt;Bedrock model IDs&lt;/a&gt; for the latest available version.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  For Non-Image Files
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File Type&lt;/th&gt;
&lt;th&gt;Enrichment Strategy&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PDF&lt;/td&gt;
&lt;td&gt;Extract text → summarize with Claude&lt;/td&gt;
&lt;td&gt;$0.01-0.05&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSV/Parquet&lt;/td&gt;
&lt;td&gt;Schema extraction + row count&lt;/td&gt;
&lt;td&gt;~$0 (metadata only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audio&lt;/td&gt;
&lt;td&gt;Transcribe → summarize&lt;/td&gt;
&lt;td&gt;$0.02-0.10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Video&lt;/td&gt;
&lt;td&gt;Frame sampling → Vision&lt;/td&gt;
&lt;td&gt;$0.05-0.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CAD/3D&lt;/td&gt;
&lt;td&gt;Metadata extraction only&lt;/td&gt;
&lt;td&gt;~$0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Vector Embeddings: Titan Embeddings V2
&lt;/h2&gt;

&lt;p&gt;Every file gets a 1024-dimensional vector embedding based on its content or AI-generated description:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bedrock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amazon.titan-embed-text-v2:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inputText&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;summary_text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# AI-generated description
&lt;/span&gt;        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dimensions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;normalize&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;body&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;())[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;embedding&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# → [0.023, -0.041, 0.089, ...] (1024 floats)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why 1024 Dimensions?
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimensions&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;th&gt;Accuracy&lt;/th&gt;
&lt;th&gt;Storage&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;256&lt;/td&gt;
&lt;td&gt;Lowest&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;1KB/file&lt;/td&gt;
&lt;td&gt;High-volume, cost-sensitive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;512&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Better&lt;/td&gt;
&lt;td&gt;2KB/file&lt;/td&gt;
&lt;td&gt;General purpose&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1024&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;High&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4KB/file&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Recommended balance&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1536&lt;/td&gt;
&lt;td&gt;Higher&lt;/td&gt;
&lt;td&gt;Highest&lt;/td&gt;
&lt;td&gt;6KB/file&lt;/td&gt;
&lt;td&gt;Maximum precision&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;1024 dimensions was a practical default for this PoC. Validate 256/512/1024/1536 dimensions against your own top-k relevance and storage/cost targets (~4KB per file × 100K files = 400MB total at 1024-dim).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pricing note&lt;/strong&gt;: Titan Embeddings V2 charges per 1K &lt;strong&gt;input&lt;/strong&gt; tokens ($0.00002). The cost is the same whether you request 256, 512, or 1024 dimensions — so there's no cost penalty for choosing higher dimensions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Embedding Storage in Iceberg
&lt;/h3&gt;

&lt;p&gt;Embeddings are stored as &lt;code&gt;binary&lt;/code&gt; type in the Iceberg table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;

&lt;span class="c1"&gt;# Convert float list to binary for Iceberg storage
&lt;/span&gt;&lt;span class="n"&gt;embedding_bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Write to Iceberg table
&lt;/span&gt;&lt;span class="n"&gt;arrow_table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;file_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;file_id&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;embedding_vector&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;embedding_bytes&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;enrichment_status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;completed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arrow_table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Important: Append-Only Writes and Deduplication
&lt;/h3&gt;

&lt;p&gt;Iceberg on S3 Tables uses append-only writes. If you enrich the same file twice (e.g., after a retry), you'll get duplicate records. Use this dedup pattern in queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;ranked&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;file_id&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;modified_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;rn&lt;/span&gt;
  &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="nv"&gt;"s3tablescatalog/fsxn-metadata-catalog"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;"metadata"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;"unstructured_files"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;ranked&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;rn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;is_deleted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;S3 Tables auto-compaction handles the storage overhead of duplicates over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vector Search: OpenSearch Serverless NextGen
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Scale-to-Zero Revolution
&lt;/h3&gt;

&lt;p&gt;Before May 2026, OpenSearch Serverless had a &lt;strong&gt;minimum cost of ~$350/month&lt;/strong&gt; (2 OCUs always running). This made it impractical for PoC and dev environments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OpenSearch Serverless NextGen&lt;/strong&gt; (GA May 2026) introduces &lt;strong&gt;scale-to-zero&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;State&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;th&gt;Latency&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Idle (no queries)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0/month&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cold start (first query)&lt;/td&gt;
&lt;td&gt;$0.24/OCU-hour&lt;/td&gt;
&lt;td&gt;10-30 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Warm (subsequent queries)&lt;/td&gt;
&lt;td&gt;$0.24/OCU-hour&lt;/td&gt;
&lt;td&gt;~54ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This changes the economics completely: you can keep vector search compute cost near zero until you actually need it.&lt;/p&gt;

&lt;h3&gt;
  
  
  kNN Search Implementation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;opensearchpy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenSearch&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;requests_aws4auth&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AWS4Auth&lt;/span&gt;

&lt;span class="c1"&gt;# Generate query embedding
&lt;/span&gt;&lt;span class="n"&gt;query_embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_embedding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;find invoice or payment documents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# kNN search
&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fsxn-metadata-embeddings&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;size&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;knn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;embedding_vector&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;vector&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;query_embedding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Vector search requires OpenSearch — you cannot perform kNN queries directly on the &lt;code&gt;embedding_vector&lt;/code&gt; binary column in Athena. The Iceberg table stores embeddings for durability; OpenSearch provides the search interface.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Search Results (Measured)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query: "find invoice or payment documents"

Results:
  1. invoice_sample.png (score: 0.6749)
     Classification: Invoice
     Summary: "Invoice #INV-2024-..."

  2. (other similar files ranked by cosine similarity)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Score interpretation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;0.9+: Near-identical content&lt;/li&gt;
&lt;li&gt;0.7-0.9: Highly similar&lt;/li&gt;
&lt;li&gt;0.5-0.7: Related topic&lt;/li&gt;
&lt;li&gt;&amp;lt; 0.5: Weak or no relation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our score of 0.67 for "invoice or payment documents" → &lt;code&gt;invoice_sample.png&lt;/code&gt; is reasonable — the query is broad, and the match is correct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Improving search scores&lt;/strong&gt;: Use more specific queries ("Q4 2024 invoice from vendor ABC" vs "find invoices"), enrich files with more detailed summaries, or increase embedding dimensions to 1536 for higher precision at ~50% more storage cost.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;These score bands are demo heuristics, not universal thresholds. Calibrate thresholds with labeled examples for each document type and business workflow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Complete Pipeline
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Processing Flow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New file detected (FPolicy event or batch scan)
       │
       ▼
┌─ Is it an image? ──────────────────────────┐
│  YES → Claude Vision classification        │
│  NO  → Metadata-only (file type, size)     │
└────────────────────────────────────────────┘
       │
       ▼
┌─ Generate embedding ──────────────────────┐
│  Input: classification + summary text     │
│  Output: 1024-dim normalized vector       │
└───────────────────────────────────────────┘
       │
       ▼
┌─ Write to S3 Tables (Iceberg) ────────────┐
│  classification, confidence_score,        │
│  summary, embedding_vector,               │
│  enrichment_status = "completed"          │
│  index_status = "pending"                 │
└───────────────────────────────────────────┘
       │
       ▼
┌─ Index in OpenSearch ─────────────────────┐
│  file_id, embedding_vector, metadata      │
│  (for kNN similarity search)              │
│  index_status = "indexed" / "stale" / "failed" │
└───────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Error Handling
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Error&lt;/th&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bedrock ThrottlingException&lt;/td&gt;
&lt;td&gt;Exponential backoff (1s, 2s, 4s)&lt;/td&gt;
&lt;td&gt;Retry up to 3 times&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bedrock ModelNotReadyException&lt;/td&gt;
&lt;td&gt;Wait 5s, retry&lt;/td&gt;
&lt;td&gt;Model warming up (first invocation)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File read failure (S3 AP)&lt;/td&gt;
&lt;td&gt;Mark as &lt;code&gt;failed&lt;/code&gt;, retry next cycle&lt;/td&gt;
&lt;td&gt;No data loss&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low confidence (&amp;lt; 0.3)&lt;/td&gt;
&lt;td&gt;Mark as &lt;code&gt;low_confidence&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Human review queue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lambda timeout (large files)&lt;/td&gt;
&lt;td&gt;Fallback to ECS Fargate&lt;/td&gt;
&lt;td&gt;No timeout limit&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Monitoring the Pipeline
&lt;/h3&gt;

&lt;p&gt;How do you know when something goes wrong? Set up these CloudWatch alarms:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;Alert Condition&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DLQ message count&lt;/td&gt;
&lt;td&gt;CloudWatch (SQS)&lt;/td&gt;
&lt;td&gt;&amp;gt; 0&lt;/td&gt;
&lt;td&gt;Inspect DLQ messages, redrive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lambda error rate&lt;/td&gt;
&lt;td&gt;CloudWatch (Lambda)&lt;/td&gt;
&lt;td&gt;&amp;gt; 5% for 5 min&lt;/td&gt;
&lt;td&gt;Check logs, Iceberg commit conflict?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bedrock throttling&lt;/td&gt;
&lt;td&gt;CloudWatch (Bedrock)&lt;/td&gt;
&lt;td&gt;&amp;gt; 10/min&lt;/td&gt;
&lt;td&gt;Reduce request rate, adjust backoff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enrichment backlog&lt;/td&gt;
&lt;td&gt;Athena query (pending count)&lt;/td&gt;
&lt;td&gt;&amp;gt; 1000&lt;/td&gt;
&lt;td&gt;Increase Lambda concurrency or batch size&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenSearch index size&lt;/td&gt;
&lt;td&gt;OpenSearch metrics&lt;/td&gt;
&lt;td&gt;&amp;gt; 80% capacity&lt;/td&gt;
&lt;td&gt;Add shards or rotate index&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Quick health check: DLQ + Lambda errors in one command&lt;/span&gt;
aws cloudwatch get-metric-data &lt;span class="nt"&gt;--metric-data-queries&lt;/span&gt; &lt;span class="s1"&gt;'[
  {"Id":"dlq","MetricStat":{"Metric":{"Namespace":"AWS/SQS","MetricName":"ApproximateNumberOfMessagesVisible","Dimensions":[{"Name":"QueueName","Value":"fsxn-metadata-sync-dlq"}]},"Period":300,"Stat":"Sum"}},
  {"Id":"errors","MetricStat":{"Metric":{"Namespace":"AWS/Lambda","MetricName":"Errors","Dimensions":[{"Name":"FunctionName","Value":"fsxn-metadata-sync"}]},"Period":300,"Stat":"Sum"}}
]'&lt;/span&gt; &lt;span class="nt"&gt;--start-time&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nt"&gt;-v-1H&lt;/span&gt; +%Y-%m-%dT%H:%M:%S&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;--end-time&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; +%Y-%m-%dT%H:%M:%S&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For detailed operational monitoring guidance, see the &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/docs/en/iceberg-metadata-catalog.md#operational-monitoring" rel="noopener noreferrer"&gt;Operational Monitoring section&lt;/a&gt; in the architecture document.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost at Scale
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Volume&lt;/th&gt;
&lt;th&gt;AI Cost&lt;/th&gt;
&lt;th&gt;Embedding Cost&lt;/th&gt;
&lt;th&gt;OpenSearch&lt;/th&gt;
&lt;th&gt;Total&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;100 files/day&lt;/td&gt;
&lt;td&gt;$1/day&lt;/td&gt;
&lt;td&gt;$0.002/day&lt;/td&gt;
&lt;td&gt;$0 (idle)&lt;/td&gt;
&lt;td&gt;~$30/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,000 files/day&lt;/td&gt;
&lt;td&gt;$10/day&lt;/td&gt;
&lt;td&gt;$0.02/day&lt;/td&gt;
&lt;td&gt;~$42/month&lt;/td&gt;
&lt;td&gt;~$342/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10,000 files/day&lt;/td&gt;
&lt;td&gt;$100/day&lt;/td&gt;
&lt;td&gt;$0.20/day&lt;/td&gt;
&lt;td&gt;~$84/month&lt;/td&gt;
&lt;td&gt;~$3,084/month&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;At 10K files/day, consider batch processing during off-hours and Provisioned Throughput for Bedrock to reduce per-request cost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cost optimization tip&lt;/strong&gt;: Not all files need AI enrichment. A common pattern: images → Vision classification, documents → text extraction + embedding, data files (CSV/Parquet) → metadata only (no AI cost). This can reduce AI costs by 60-80% depending on your file mix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Batch Inference&lt;/strong&gt;: For initial bulk enrichment (10K+ files), Bedrock Batch Inference can reduce costs by ~50% compared to real-time invocations. Use real-time for incremental new files, batch for backfill.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Batch Inference example — submit a batch job for bulk classification
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="n"&gt;bedrock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bedrock&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ap-northeast-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Prepare input JSONL file in S3 (one request per line)
# Each line: {"recordId":"file-001","modelInput":{"anthropic_version":"bedrock-2023-05-31",...}}
&lt;/span&gt;
&lt;span class="c1"&gt;# 2. Create batch inference job
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bedrock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_model_invocation_job&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;jobName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;metadata-enrichment-backfill&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-3-haiku-20240307-v1:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;roleArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arn:aws:iam::&amp;lt;ACCOUNT&amp;gt;:role/BedrockBatchRole&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;inputDataConfig&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;s3InputDataConfig&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;s3Uri&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;s3://my-bucket/batch-input/enrichment-requests.jsonl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;outputDataConfig&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;s3OutputDataConfig&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;s3Uri&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;s3://my-bucket/batch-output/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Job runs asynchronously — results written to S3 when complete
# Typical processing: 10K files in ~30 minutes at ~50% cost reduction
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The batch input JSONL contains prompts, file references, or extracted/redacted text depending on your design. It does not require copying the original raw files from FSx for ONTAP to S3. If images are included as base64, treat the JSONL as temporary processing data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Batch job monitoring&lt;/strong&gt;: Use EventBridge rules to detect Bedrock batch job state changes (&lt;code&gt;COMPLETED&lt;/code&gt;, &lt;code&gt;FAILED&lt;/code&gt;). Route to SNS → Lambda to automatically write results back to S3 Tables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prompt Caching&lt;/strong&gt;: If using the same system prompt across all classifications (recommended), Bedrock's Prompt Caching feature can reduce input token costs by up to 90% for repeated prompts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EMR Spark for large-scale backfill&lt;/strong&gt;: For initial backfill or re-enrichment of 100K+ files, Spark on EMR Serverless or EMR on EC2 can be used as an alternative to Lambda/Fargate. EMR 7.13.0+ supports &lt;a href="https://docs.aws.amazon.com/glue/latest/dg/connect-glu-iceberg-rest.html" rel="noopener noreferrer"&gt;Glue as an Iceberg REST catalog&lt;/a&gt;, enabling distributed metadata writes with Lake Formation governance. Verified 2026-06-02: SELECT, COUNT, and time travel all work on EMR Serverless 7.13.0. Use Lambda for incremental (event-driven) processing and Spark for bulk operations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Search Index Consistency
&lt;/h2&gt;

&lt;p&gt;OpenSearch is a derived index, not the system of record. S3 Tables / Iceberg remains the metadata source of truth.&lt;/p&gt;

&lt;p&gt;Recommended controls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store &lt;code&gt;iceberg_snapshot_id&lt;/code&gt; in OpenSearch documents for traceability&lt;/li&gt;
&lt;li&gt;Store &lt;code&gt;embedding_model_id&lt;/code&gt; and &lt;code&gt;prompt_version&lt;/code&gt; in both Iceberg and OpenSearch&lt;/li&gt;
&lt;li&gt;Reconcile OpenSearch index against latest Iceberg view periodically&lt;/li&gt;
&lt;li&gt;Mark &lt;code&gt;index_status&lt;/code&gt;: pending / indexed / stale / failed&lt;/li&gt;
&lt;li&gt;If search returns a stale result, fall back to Athena query on the base table&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FPolicy Event Design
&lt;/h2&gt;

&lt;p&gt;For incremental metadata sync via ONTAP FPolicy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;batch scan&lt;/strong&gt; for initial backfill (not FPolicy)&lt;/li&gt;
&lt;li&gt;Use FPolicy only for &lt;strong&gt;incremental changes&lt;/strong&gt; after initial catalog population&lt;/li&gt;
&lt;li&gt;Prefer &lt;code&gt;create&lt;/code&gt; / &lt;code&gt;close-with-modification&lt;/code&gt; / &lt;code&gt;rename&lt;/code&gt; / &lt;code&gt;delete&lt;/code&gt; events&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid&lt;/strong&gt; &lt;code&gt;read&lt;/code&gt; / &lt;code&gt;open&lt;/code&gt; events (excessive volume, no catalog value)&lt;/li&gt;
&lt;li&gt;Apply path and extension filters to reduce event noise&lt;/li&gt;
&lt;li&gt;Add backpressure via SQS batching (not fan-out Lambda per event)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;FPolicy can significantly impact file system throughput if configured too broadly. Filter to only the operations and paths that matter for catalog updates.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Hybrid Search Pattern
&lt;/h2&gt;

&lt;p&gt;For production discovery, vector search should be combined with lexical filters and keyword search:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lexical search&lt;/strong&gt;: file_name, path, classification, summary, tags&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vector search&lt;/strong&gt;: embedding similarity (kNN)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filters&lt;/strong&gt;: tenant_id, sensitivity_level, file_type, path_classification, last_modified&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OpenSearch supports both search and vector collection types. Use a single index with both text fields and vector fields for hybrid queries. S3 Tables / Iceberg remains the metadata source of truth; OpenSearch is the serving index.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For sensitive workloads, use VPC interface endpoints for Bedrock Runtime and S3 VPC endpoints for batch input/output. See &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/genai/bedrock-private-connectivity.md" rel="noopener noreferrer"&gt;&lt;code&gt;genai/bedrock-private-connectivity.md&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Storage Tier Impact During Backfill
&lt;/h2&gt;

&lt;p&gt;Initial AI enrichment may read cold files from capacity pool storage, causing higher latency and throughput consumption.&lt;/p&gt;

&lt;p&gt;Recommended controls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run backfill during off-hours (minimize impact on production NFS/SMB)&lt;/li&gt;
&lt;li&gt;Limit Lambda concurrency during backfill&lt;/li&gt;
&lt;li&gt;Enrich only selected file types first (images → documents → data files)&lt;/li&gt;
&lt;li&gt;Monitor FSx capacity pool read activity via CloudWatch&lt;/li&gt;
&lt;li&gt;Separate backfill cost from steady-state cost in planning&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Backfill vs Incremental Cost Model
&lt;/h2&gt;

&lt;p&gt;Separate cost planning for:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Phase&lt;/th&gt;
&lt;th&gt;Scope&lt;/th&gt;
&lt;th&gt;Cost driver&lt;/th&gt;
&lt;th&gt;Optimization&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Initial backfill&lt;/td&gt;
&lt;td&gt;All existing files (e.g., 100K)&lt;/td&gt;
&lt;td&gt;Bedrock AI at scale&lt;/td&gt;
&lt;td&gt;Batch Inference (~50% savings)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Daily incremental&lt;/td&gt;
&lt;td&gt;New/modified files (e.g., 1000/day)&lt;/td&gt;
&lt;td&gt;Real-time Lambda + Bedrock&lt;/td&gt;
&lt;td&gt;Selective enrichment by file type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Re-enrichment&lt;/td&gt;
&lt;td&gt;After prompt/model change&lt;/td&gt;
&lt;td&gt;Full re-scan of enriched files&lt;/td&gt;
&lt;td&gt;Batch + compare confidence delta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenSearch reindex&lt;/td&gt;
&lt;td&gt;After schema/embedding change&lt;/td&gt;
&lt;td&gt;Index rebuild&lt;/td&gt;
&lt;td&gt;Off-hours, parallel shards&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;The largest cost spike is typically the initial backfill, not steady-state. Plan Bedrock Batch Inference and off-peak scheduling for the first catalog population.&lt;/p&gt;

&lt;p&gt;For adjustable assumptions, see &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/verification-evidence/cost-assumptions.yaml" rel="noopener noreferrer"&gt;&lt;code&gt;verification-evidence/cost-assumptions.yaml&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Enrich pending files with AI&lt;/span&gt;
python3 demo/scripts/demo-enrich.py &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--table-bucket-arn&lt;/span&gt; &amp;lt;TABLE_BUCKET_ARN&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--ap-alias&lt;/span&gt; &amp;lt;AP_ALIAS&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-files&lt;/span&gt; 10

&lt;span class="c"&gt;# Search by natural language&lt;/span&gt;
python3 demo/scripts/demo-search.py &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"find documents about contracts or agreements"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  AI Safety and Human Review Boundary
&lt;/h2&gt;

&lt;p&gt;AI enrichment should not be treated as authoritative classification for regulated data without human review.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;For regulated industries&lt;/strong&gt;: AI enrichment is assistive metadata generation, not authoritative classification. Final regulatory classification must be confirmed by data owners, security, legal, and compliance teams. This system provides AI-generated signals to accelerate human review — it does not replace it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deterministic vs AI boundary&lt;/strong&gt;: AI generates classifications and summaries, but pipeline state transitions, retry logic, deduplication, access controls, and audit evidence are deterministic and version-controlled. The deterministic pipeline guarantees reproducibility; AI provides enrichment quality.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Recommended controls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Human review queue for low-confidence classifications (&amp;lt; 0.7)&lt;/li&gt;
&lt;li&gt;Sampling review for high-confidence results (periodic spot-check)&lt;/li&gt;
&lt;li&gt;False negative testing for PII detection&lt;/li&gt;
&lt;li&gt;Model/prompt version recorded in metadata (&lt;code&gt;enriched_at&lt;/code&gt; + model ID)&lt;/li&gt;
&lt;li&gt;Re-enrichment policy when model or prompt changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Recommended metadata columns for AI lineage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;classification_model_id&lt;/code&gt; — which model produced the classification&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;embedding_model_id&lt;/code&gt; — which model produced the embedding&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;prompt_version&lt;/code&gt; — version of the classification prompt&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;enrichment_code_version&lt;/code&gt; — version of the enrichment Lambda/script&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;enriched_at&lt;/code&gt; — timestamp of enrichment&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;human_review_status&lt;/code&gt; — pending / approved / rejected&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;human_reviewed_by&lt;/code&gt; — reviewer identity (if applicable)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;human_reviewed_at&lt;/code&gt; — review timestamp&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Evaluation Plan
&lt;/h2&gt;

&lt;p&gt;For production use, do not rely only on model-reported confidence. Create a labeled validation set and measure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Classification accuracy (overall and per document type)&lt;/li&gt;
&lt;li&gt;Precision / recall per category&lt;/li&gt;
&lt;li&gt;False positive rate for PII detection&lt;/li&gt;
&lt;li&gt;False negative rate for PII detection&lt;/li&gt;
&lt;li&gt;Embedding search top-k relevance (nDCG@5, MRR)&lt;/li&gt;
&lt;li&gt;Human review acceptance rate&lt;/li&gt;
&lt;li&gt;Cost per accepted classification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Business acceptance metrics&lt;/strong&gt; (beyond model accuracy):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Time saved per analyst for file discovery&lt;/li&gt;
&lt;li&gt;Dataset discovery lead-time reduction (days → hours target)&lt;/li&gt;
&lt;li&gt;Business owner approval rate for AI classifications&lt;/li&gt;
&lt;li&gt;Cost per useful search result&lt;/li&gt;
&lt;li&gt;False negative risk by document category (which misses matter most?)&lt;/li&gt;
&lt;li&gt;Governance coverage (% of assets searchable in BI/AI tools)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The 7/7 PII detection result was measured on a controlled synthetic sample. Production use requires evaluation with domain-specific documents, false-positive/false-negative review, human approval workflow, and legal/compliance sign-off.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Snowflake users&lt;/strong&gt;: Snowflake can now directly query S3 Tables Iceberg metadata via Glue REST + VENDED_CREDENTIALS (verified 2026-06-05). Additionally, you can sync redacted metadata into Snowflake-managed tables for Cortex Search / Snowflake Intelligence business-facing discovery. In this PoC, OpenSearch remains the AWS-native vector search component.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;In &lt;strong&gt;Part 3&lt;/strong&gt;, we'll cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lake Formation governance&lt;/strong&gt;: Column-level access control on metadata&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PII detection and anonymization&lt;/strong&gt;: Comprehend (English) + Bedrock Claude (Japanese)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-platform access&lt;/strong&gt;: What works and what doesn't with Databricks and Snowflake&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Clean Room pattern&lt;/strong&gt;: Separate tables for sensitive vs. anonymized metadata&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Full code: &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/tree/main/integrations/iceberg-metadata-catalog" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/fsxn-lakehouse-integrations&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>iceberg</category>
      <category>datalake</category>
      <category>amazonfsxfornetappontap</category>
    </item>
    <item>
      <title>From Hours to Seconds: An AI-Powered Metadata Catalog for Unstructured Data on FSx for ONTAP</title>
      <dc:creator>Yoshiki Fujiwara(藤原 善基)@AWS Community Builder</dc:creator>
      <pubDate>Mon, 08 Jun 2026 16:26:50 +0000</pubDate>
      <link>https://dev.to/aws-builders/from-hours-to-seconds-an-ai-powered-metadata-catalog-for-unstructured-data-on-fsx-for-ontap-5f54</link>
      <guid>https://dev.to/aws-builders/from-hours-to-seconds-an-ai-powered-metadata-catalog-for-unstructured-data-on-fsx-for-ontap-5f54</guid>
      <description>&lt;h2&gt;
  
  
  What Works Now vs What Requires Validation
&lt;/h2&gt;

&lt;p&gt;This article separates verified AWS-native capabilities from cross-platform paths that still require validation. The core pattern — keeping raw files on FSx for ONTAP and cataloging only metadata in S3 Tables — is verified. Databricks paths are still evolving. Snowflake Glue REST + VENDED_CREDENTIALS and External Stage paths are verified in this PoC, with governance limitations noted below. Validate all cross-platform paths in your own environment before production use.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS Native PoC (Athena + S3 Tables + Bedrock + OpenSearch + Lake Formation)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Verified&lt;/td&gt;
&lt;td&gt;Full end-to-end in 42 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Glue Iceberg REST endpoint access&lt;/td&gt;
&lt;td&gt;✅ Verified&lt;/td&gt;
&lt;td&gt;Both S3 Tables REST and Glue REST confirmed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lake Formation table-level governance&lt;/td&gt;
&lt;td&gt;✅ Verified&lt;/td&gt;
&lt;td&gt;Grant/revoke/audit working&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lake Formation column-level exclusion&lt;/td&gt;
&lt;td&gt;⚠️ Observed limitation&lt;/td&gt;
&lt;td&gt;Failed on tested federated catalog path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databricks SQL Warehouse direct&lt;/td&gt;
&lt;td&gt;⚠️ Observed limitation&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;iceberg_rest&lt;/code&gt; connection type not supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databricks Spark + Iceberg REST&lt;/td&gt;
&lt;td&gt;❌ Blocked by UC&lt;/td&gt;
&lt;td&gt;spark.conf.set and cluster config both fail; UC Foreign Catalog required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databricks UC Foreign Catalog&lt;/td&gt;
&lt;td&gt;❌ Still blocked&lt;/td&gt;
&lt;td&gt;Retested post-&lt;a href="https://www.databricks.com/blog/unity-catalog-and-next-era-apache-icebergtm" rel="noopener noreferrer"&gt;Foreign Iceberg GA&lt;/a&gt; (2026-06-09): Glue Connection ✅, Credentials ✅, but External Location fails — S3 Tables internal bucket rejects standard S3 API validation. No bypass available.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databricks Delta Sharing via S3 AP&lt;/td&gt;
&lt;td&gt;❌ Confirmed&lt;/td&gt;
&lt;td&gt;Sharing server uses same UC credentials; not a workaround for S3 AP session policy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databricks NFS → UC Volume&lt;/td&gt;
&lt;td&gt;❌ Confirmed&lt;/td&gt;
&lt;td&gt;Cloud storage URIs only; internal feature request exists&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databricks UC audit logging&lt;/td&gt;
&lt;td&gt;✅ Confirmed&lt;/td&gt;
&lt;td&gt;External engine access fully logged&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snowflake via Glue REST (VENDED_CREDENTIALS)&lt;/td&gt;
&lt;td&gt;✅ Verified&lt;/td&gt;
&lt;td&gt;Explicit &lt;code&gt;ACCESS_DELEGATION_MODE = VENDED_CREDENTIALS&lt;/code&gt;; CREATE TABLE + SELECT + COUNT + AUTO_REFRESH all working (2026-06-05)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snowflake External Stage (FSx S3 AP)&lt;/td&gt;
&lt;td&gt;✅ Verified&lt;/td&gt;
&lt;td&gt;LIST, SELECT/COPY, and TO_FILE + Cortex AI all verified&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important distinction&lt;/strong&gt;: This pattern does not use FSx for ONTAP S3 Access Points as an Iceberg warehouse. Raw files stay on FSx for ONTAP, while only the metadata catalog is written to S3 Tables. Direct Iceberg table writes to FSx for ONTAP S3 Access Points are tracked separately as a &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/tree/main/integrations/iceberg" rel="noopener noreferrer"&gt;known limitation&lt;/a&gt; because Iceberg commit behavior and S3FileIO compatibility require additional validation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  This is an Iceberg Adoption Pattern, Not a Raw-Data Migration
&lt;/h3&gt;

&lt;p&gt;This pattern does not convert the original unstructured files into Iceberg table data. Instead, it adopts Iceberg for the metadata layer only.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scope&lt;/th&gt;
&lt;th&gt;What happens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data files&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not migrated. Raw files remain on FSx for ONTAP.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Metadata table&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Newly created as an Iceberg table on S3 Tables.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Processing jobs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Metadata scan and AI enrichment jobs write append-only metadata.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Consumers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Athena, EMR, Snowflake, Databricks, and BI/search tools consume curated metadata views.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Storage Boundary: What Moves and What Doesn't
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FSx for ONTAP S3 Access Point:
  ✅ Raw file READ path only (AI enrichment input)
  ❌ NOT an Iceberg warehouse
  ❌ NOT a table commit target
  ❌ NOT bulk-copied to S3

S3 Tables:
  ✅ Iceberg METADATA table (file catalog)
  ✅ Metadata source of truth
  ✅ Query and governance target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Data movement disclosure (for regulated environments)&lt;/strong&gt;: Raw files are NOT bulk-copied to S3. However, during AI enrichment, selected file content is temporarily read via the S3 Access Point and sent to Amazon Bedrock APIs for classification/embedding. Per &lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/data-protection.html" rel="noopener noreferrer"&gt;AWS Bedrock data protection policy&lt;/a&gt;, model providers have no access to customer prompts or completions. Extracted/redacted metadata and embeddings are written to S3 Tables, OpenSearch, and optionally to Snowflake or Databricks depending on the activation path. Define your data flow boundary documentation before regulated-workload deployment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Problem: Most Enterprise Unstructured Data is Difficult to Discover and Govern
&lt;/h2&gt;

&lt;p&gt;Most organizations store terabytes of unstructured data — PDFs, images, CAD files, sensor logs — on network-attached storage. This data is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Undiscoverable&lt;/strong&gt;: "Where is that invoice from last quarter?" requires manual searching or asking colleagues&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Governed at the file-system layer, but not classified or searchable&lt;/strong&gt; from analytics and AI workflows&lt;/li&gt;
&lt;li&gt;Audit trails may exist at the file-system layer, but they are often not unified with analytics and AI query activity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of this as &lt;strong&gt;unstructured-data modernization&lt;/strong&gt;: inventory first, classify selectively, govern metadata, and activate only what is needed — without bulk-copying the raw files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Business Outcomes (Beyond Technical Metrics)
&lt;/h3&gt;

&lt;p&gt;This pattern is not only about faster file search. It is about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reducing dataset discovery lead time&lt;/strong&gt; for AI projects (days → hours)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improving PII visibility&lt;/strong&gt; across the organization (unknown → 95%+ coverage target)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lowering duplicate storage cost&lt;/strong&gt; ($230-256/month eliminated for 10TB)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Creating governed metadata products&lt;/strong&gt; for analytics and AI teams&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enabling AI-readiness&lt;/strong&gt; without raw-data copy or migration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Activating governed metadata in Snowflake AI Data Cloud&lt;/strong&gt; for Cortex Search, semantic Q&amp;amp;A, executive dashboards, and business-facing file discovery&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The traditional solution? Copy everything to S3 and build a catalog. But at 10TB, that's &lt;strong&gt;~$230-256/month&lt;/strong&gt; just for the copy — plus sync pipelines, duplicate governance, and data drift.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: Hot Metadata × Cold Data
&lt;/h2&gt;

&lt;p&gt;What if we could catalog every file &lt;em&gt;without&lt;/em&gt; moving it?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────┐
│  HOT: Metadata (Apache Iceberg on S3 Tables)            │
│  • File path, type, size, timestamps                    │
│  • AI classification + confidence score                 │
│  • Vector embedding (1024-dim, similarity search)       │
│  • PII detection flag                                   │
│  • Cost: ~$5-15/month for 100K files                    │
└────────────────────────┬────────────────────────────────┘
                         │ file_path reference
┌────────────────────────▼────────────────────────────────┐
│  COLD: Actual Files (FSx for ONTAP)                     │
│  • PDF, images, CAD, video, audio, logs                 │
│  • Deduplication (50-70% storage savings typical*)      │
│  • NFS/SMB (existing workflows) + S3 AP (AI/analytics)  │
│  • No bulk raw-data copy required                       │
└─────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key insight&lt;/strong&gt;: Keep the data where it is. Move only the metadata into a queryable format.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FSx for ONTAP ──S3 Access Point──→ AI Enrichment (Bedrock)
       │                                    │
       │                                    ▼
       │                          S3 Tables (Iceberg)
       │                                    │
       │                                    ▼
       │                          ┌──────────────────┐
       │                          │ Query Engines    │
       │                          │ • Athena (SQL)   │
       │                          │ • OpenSearch     │
       │                          │   (vector kNN)   │
       │                          │ • Lake Formation │
       │                          │   (governance)   │
       │                          └──────────────────┘
       │
       └──NFS/SMB──→ Existing applications (unchanged)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Observability&lt;/strong&gt; (production add-on):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;       ┌──────────────────────────────────────┐
       │  • CloudWatch Metrics + Alarms       │
       │  • CloudWatch Logs (Lambda/SQS)      │
       │  • CloudTrail (governance audit)     │
       │  • OpenSearch Dashboards (search UX) │
       │  • FSx metrics (throughput, IOPS,    │
       │    latency, capacity pool reads)     │
       └──────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Components&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;FSx for ONTAP S3 Access Point&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Read files for AI processing (no copy)&lt;/td&gt;
&lt;td&gt;Included with FSx&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;S3 Tables&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AWS managed Apache Iceberg table service (auto-compaction, REST endpoint)&lt;/td&gt;
&lt;td&gt;~$5/month metadata&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bedrock Claude Vision&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Image classification&lt;/td&gt;
&lt;td&gt;~$0.01/file in this demo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Titan Embeddings V2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1024-dim vectors for similarity search&lt;/td&gt;
&lt;td&gt;$0.00002/1K input tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OpenSearch Serverless NextGen&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;kNN vector search (scale-to-zero)&lt;/td&gt;
&lt;td&gt;$0 idle compute when inactive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lake Formation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Metadata access governance&lt;/td&gt;
&lt;td&gt;No additional Lake Formation charge&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;S3 Tables Iceberg REST endpoint: &lt;code&gt;https://s3tables.&amp;lt;region&amp;gt;.amazonaws.com/iceberg&lt;/code&gt;&lt;br&gt;
Check &lt;a href="https://aws.amazon.com/s3/tables/" rel="noopener noreferrer"&gt;S3 Tables availability&lt;/a&gt; for regional support before deployment.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Deduplication ratio is a general ONTAP range. Actual savings depend on data characteristics and were not measured in this PoC.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  PoC Results (Verified 2026-05-31)
&lt;/h2&gt;

&lt;p&gt;We built and verified this end-to-end in a single day. Here's what we measured:&lt;/p&gt;

&lt;h3&gt;
  
  
  S3 Tables Access Paths: Which Endpoint Should You Use?
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Access path&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;th&gt;Governance path&lt;/th&gt;
&lt;th&gt;Verified&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S3 Tables Iceberg REST (&lt;code&gt;s3tables.&amp;lt;region&amp;gt;.amazonaws.com/iceberg&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Direct Iceberg client / simple PoC&lt;/td&gt;
&lt;td&gt;IAM + S3 Tables permissions&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS Glue Iceberg REST (&lt;code&gt;glue.&amp;lt;region&amp;gt;.amazonaws.com/iceberg&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Production analytics integration&lt;/td&gt;
&lt;td&gt;IAM + Lake Formation&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Athena via Glue federated catalog&lt;/td&gt;
&lt;td&gt;SQL analytics&lt;/td&gt;
&lt;td&gt;Lake Formation + Athena&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PyIceberg local client&lt;/td&gt;
&lt;td&gt;Lightweight validation&lt;/td&gt;
&lt;td&gt;IAM/LF depending on endpoint&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;For production workloads with centralized governance, the &lt;strong&gt;AWS Glue Iceberg REST endpoint&lt;/strong&gt; is recommended over the S3 Tables direct endpoint. See &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-tables-integrating-glue-endpoint.html" rel="noopener noreferrer"&gt;AWS docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Catalog authority rule&lt;/strong&gt;: S3 Tables + Glue is the authoritative catalog for this metadata table in this PoC. Other engines should consume the table through the authoritative catalog or a controlled metadata activation path. Do not configure multiple writable catalogs for the same Iceberg table — dual-write causes split-brain and potential data corruption.&lt;/p&gt;

&lt;p&gt;Athena Iceberg behavior depends on Athena engine version, Iceberg version, Glue/Lake Formation integration, and table maintenance state. Validate DDL/DML requirements separately before using this as a write-heavy production catalog.&lt;/p&gt;

&lt;p&gt;Verification details are recorded in &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/verification-evidence/evidence-record.yaml" rel="noopener noreferrer"&gt;evidence-record.yaml&lt;/a&gt; and &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/verification-evidence/cross-platform-compatibility.yaml" rel="noopener noreferrer"&gt;cross-platform-compatibility.yaml&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Before vs After
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;File discovery time&lt;/td&gt;
&lt;td&gt;Minutes-hours&lt;/td&gt;
&lt;td&gt;&amp;lt; 2 seconds&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;100x+ at scale&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI classification&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Automatic (6 sec/file)&lt;/td&gt;
&lt;td&gt;Fully automated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage cost (10TB)&lt;/td&gt;
&lt;td&gt;~$250/month (S3 copy)&lt;/td&gt;
&lt;td&gt;$5-15/month (metadata only)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;95% reduction&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Metadata query governance&lt;/td&gt;
&lt;td&gt;Not applicable&lt;/td&gt;
&lt;td&gt;100% in this PoC&lt;/td&gt;
&lt;td&gt;Complete for metadata queries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Idle compute/search cost&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Near $0 when inactive&lt;/td&gt;
&lt;td&gt;Persistent metadata/logs may still incur small charges&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Search Time Scaling (Measured + Projected)
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Files&lt;/th&gt;
&lt;th&gt;ListObjectsV2&lt;/th&gt;
&lt;th&gt;Athena SQL&lt;/th&gt;
&lt;th&gt;Speedup&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;892 ms&lt;/td&gt;
&lt;td&gt;3.0 sec&lt;/td&gt;
&lt;td&gt;0.3x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,000&lt;/td&gt;
&lt;td&gt;22.3 sec&lt;/td&gt;
&lt;td&gt;1.8 sec&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;12x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10,000&lt;/td&gt;
&lt;td&gt;3.7 min&lt;/td&gt;
&lt;td&gt;1.8 sec&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;124x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100,000&lt;/td&gt;
&lt;td&gt;37.2 min&lt;/td&gt;
&lt;td&gt;1.8 sec&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1,239x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,000,000&lt;/td&gt;
&lt;td&gt;371.7 min&lt;/td&gt;
&lt;td&gt;1.8 sec&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;12,389x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;At 40 files, ListObjectsV2 is faster — Athena has cold start overhead. Athena query time does not scale linearly with the number of files on FSx because it queries the Iceberg metadata table instead of listing the raw file namespace. In this controlled demo, the query stayed around ~1.8 seconds for projected file counts, but production latency depends on Iceberg metadata size, manifest count, predicate selectivity, Athena cold start, and table maintenance state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Projection method&lt;/strong&gt;: ListObjectsV2 latency was extrapolated linearly from the measured 40-file scan. This is intentionally conservative for demonstrating namespace-scan behavior, but it is not a service benchmark.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The 42-Second Demo
&lt;/h3&gt;

&lt;p&gt;Our complete demo runs all 8 steps in 42 seconds:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://asciinema.org/a/LA6F0QCkZP8fk3ZT" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fasciinema.org%2Fa%2FLA6F0QCkZP8fk3ZT.svg" alt="asciicast" width="1140" height="92"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 1: Before/After search comparison     ✅ (ListObjectsV2 vs Athena)
Step 2: Infrastructure deploy              ✅ (CloudFormation, skippable)
Step 3: Metadata scan (40 files)           ✅ (3 seconds)
Step 4: AI enrichment (Bedrock Vision)     ✅ (invoice → 0.95 confidence)
Step 5: Athena query + Time Travel         ✅ (&amp;lt; 2 seconds)
Step 6: Vector similarity search           ✅ (kNN score 0.67)
Step 7: PII detection + anonymization      ✅ (7/7 entities, all redacted)
Step 8: Cost &amp;amp; ROI analysis                ✅ ($0.07 total demo cost)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Total demo cost: $0.07&lt;/strong&gt;. After the demo, the compute/search components can scale to zero. If you retain S3 Tables metadata, logs, or audit trails, small storage/logging charges may still apply.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI Classification Results
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Classification&lt;/th&gt;
&lt;th&gt;Confidence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;invoice_sample.png&lt;/td&gt;
&lt;td&gt;Invoice&lt;/td&gt;
&lt;td&gt;0.95&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;product_inspection.png&lt;/td&gt;
&lt;td&gt;Pie Chart&lt;/td&gt;
&lt;td&gt;1.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sensor_dashboard.png&lt;/td&gt;
&lt;td&gt;IoT Sensor Dashboard&lt;/td&gt;
&lt;td&gt;0.9&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In this demo, Bedrock Claude Vision classified sample images at roughly $0.01/file with sub-10-second latency. Production cost and latency depend on image size, prompt length, model version, and retry behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vector Similarity Search
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query: "find invoice or payment documents"
→ invoice_sample.png (score: 0.6749)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OpenSearch Serverless with scale-to-zero capability (GA May 2026) provides kNN search — no minimum cost when idle. Cold start is ~10-30 seconds, warm queries are ~54ms.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Verified in this PoC environment on 2026-05-31. Check the latest &lt;a href="https://docs.aws.amazon.com/opensearch-service/latest/developerguide/serverless.html" rel="noopener noreferrer"&gt;OpenSearch Serverless documentation&lt;/a&gt; and regional availability before deployment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Governance: Lake Formation Access Control
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 1: Authorized query    → ✅ SUCCEEDED (3 rows)
Step 2: Revoke SELECT       → 🔒 BLOCKED (access denied)
Step 3: Restore SELECT      → ✅ SUCCEEDED
Step 4: CloudTrail audit    → All queries logged with user identity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Metadata queries are governed and audited. Raw file access remains governed separately by FSx file-system permissions, S3 Access Point policies, and application access paths.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost Analysis
&lt;/h2&gt;

&lt;h3&gt;
  
  
  This Demo
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bedrock AI (5 files)&lt;/td&gt;
&lt;td&gt;$0.05&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenSearch (~6 min)&lt;/td&gt;
&lt;td&gt;$0.024&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lambda + Athena&lt;/td&gt;
&lt;td&gt;$0.001&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0.07&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Projected Monthly (10TB, 100K files, 1000 changes/day)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Monthly&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S3 Tables (metadata)&lt;/td&gt;
&lt;td&gt;$5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lambda (sync + AI)&lt;/td&gt;
&lt;td&gt;$36&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bedrock (AI enrichment)&lt;/td&gt;
&lt;td&gt;$30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenSearch (business hours)&lt;/td&gt;
&lt;td&gt;$42&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SQS + misc&lt;/td&gt;
&lt;td&gt;$1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$114/month&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 copy eliminated&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;-$230-256/month&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Net effect&lt;/strong&gt;: The AI-powered catalog costs less than the S3 copy it eliminates.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Without AI enrichment&lt;/strong&gt; (metadata scan + Athena only): ~$42/month. AI processing is optional and can be enabled per-file-type.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;S3 Standard pricing: us-east-1 $0.023/GB, ap-northeast-1 $0.025/GB. Verified 2026-06-01 via AWS Pricing API.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For reproducibility, see: &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/verification-evidence/evidence-record.yaml" rel="noopener noreferrer"&gt;evidence-record.yaml&lt;/a&gt;, &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/verification-evidence/cost-assumptions.yaml" rel="noopener noreferrer"&gt;cost-assumptions.yaml&lt;/a&gt;, &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/verification-evidence/2026-05-31/comprehensive-test-results.yaml" rel="noopener noreferrer"&gt;comprehensive-test-results.yaml&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Known Limitations (Honest Assessment)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Limitation&lt;/th&gt;
&lt;th&gt;Impact&lt;/th&gt;
&lt;th&gt;Workaround&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Databricks SQL Warehouse &lt;code&gt;CREATE CONNECTION TYPE iceberg_rest&lt;/code&gt; to S3 Tables REST failed in this validation (2026-05-31)&lt;/td&gt;
&lt;td&gt;SQL Warehouse direct path unavailable in tested method&lt;/td&gt;
&lt;td&gt;Retested 2026-06-09; still blocked in tested UC path. Use curated metadata sync to UC Delta as practical workaround; support case submitted.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databricks Spark cluster: UC blocks external catalog registration (2026-06-01)&lt;/td&gt;
&lt;td&gt;Cannot use spark.conf.set or cluster config for external Iceberg catalogs&lt;/td&gt;
&lt;td&gt;UC Foreign Catalog tested 2026-06-09 — External Location validation fails against S3 Tables internal bucket. Sync metadata to UC Delta table instead.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databricks Delta Sharing: cannot bypass S3 AP session policy (2026-06-01)&lt;/td&gt;
&lt;td&gt;Sharing server uses same UC credentials&lt;/td&gt;
&lt;td&gt;DataSync → S3 → UC → Delta Sharing works for copied data; validate target table format and catalog support separately&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databricks NFS mount: cannot register as UC External Volume (2026-06-01)&lt;/td&gt;
&lt;td&gt;NFS/FUSE paths not supported for UC Volumes&lt;/td&gt;
&lt;td&gt;DataSync → S3 → UC External Location; internal feature request exists&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snowflake External Iceberg Table with S3 Tables REST endpoint was not a supported catalog type in this validation (2026-05-31)&lt;/td&gt;
&lt;td&gt;Direct S3 Tables REST path unavailable in tested method&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;Resolved (2026-06-05)&lt;/strong&gt;: Use Glue REST + explicit &lt;code&gt;ACCESS_DELEGATION_MODE = VENDED_CREDENTIALS&lt;/code&gt;. Schema must have no default External Volume. AWS prerequisite: &lt;code&gt;register-resource --with-federation&lt;/code&gt;. Lake Formation column-level filtering NOT enforced via this path.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LF column exclusion grant failed in tested S3 Tables federated catalog path&lt;/td&gt;
&lt;td&gt;Can't hide specific columns via tested grant pattern&lt;/td&gt;
&lt;td&gt;Athena Views; track AWS support status&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;At 40 files, ListObjectsV2 is faster than Athena&lt;/td&gt;
&lt;td&gt;Architecture value is at scale (100K+)&lt;/td&gt;
&lt;td&gt;Expected — Athena has cold start overhead&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Naming note&lt;/strong&gt;: Use lowercase table, namespace, and column names for S3 Tables integrated with AWS analytics services. Mixed-case names may not be visible to Athena / Glue / Lake Formation. See &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-tables-buckets-naming.html" rel="noopener noreferrer"&gt;S3 Tables naming rules&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Performance Boundaries Not Yet Validated
&lt;/h2&gt;

&lt;p&gt;This PoC validates the architecture shape, not production scale limits. The following require separate testing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;FSx throughput impact under concurrent NFS/SMB/S3 access&lt;/li&gt;
&lt;li&gt;S3 Access Point metadata operation impact under large namespace scans&lt;/li&gt;
&lt;li&gt;S3 API request concurrency vs FSx provisioned throughput capacity&lt;/li&gt;
&lt;li&gt;Impact of scan jobs on production SMB/NFS latency&lt;/li&gt;
&lt;li&gt;ListObjectsV2 pagination behavior at 1M+ files&lt;/li&gt;
&lt;li&gt;Lambda concurrency and S3 AP request throttling&lt;/li&gt;
&lt;li&gt;Iceberg manifest growth and compaction behavior&lt;/li&gt;
&lt;li&gt;Athena query latency with high snapshot counts&lt;/li&gt;
&lt;li&gt;OpenSearch indexing throughput during bulk backfill&lt;/li&gt;
&lt;li&gt;File size distribution and small-file amplification effects&lt;/li&gt;
&lt;li&gt;Cold vs warm namespace access behavior (capacity pool reads during backfill)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ONTAP Object Model Mapping
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ONTAP / FSx object&lt;/th&gt;
&lt;th&gt;Role in this pattern&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FSx file system&lt;/td&gt;
&lt;td&gt;Performance / HA boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SVM&lt;/td&gt;
&lt;td&gt;Protocol and administrative boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Volume&lt;/td&gt;
&lt;td&gt;Catalog scope and S3 Access Point attachment target&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Junction path / SMB share&lt;/td&gt;
&lt;td&gt;Existing application namespace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 Access Point&lt;/td&gt;
&lt;td&gt;S3 API boundary for AI/analytics (with associated file-system identity)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Iceberg table&lt;/td&gt;
&lt;td&gt;Metadata catalog, not raw data store&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Each S3 Access Point has an associated &lt;code&gt;OntapFileSystemIdentity&lt;/code&gt; (UNIX UID/GID or Windows domain user) that authorizes all file access through that AP. IAM policy is evaluated first, then ONTAP file-system permissions. See &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/security/s3-access-point-identity-matrix.yaml" rel="noopener noreferrer"&gt;&lt;code&gt;security/s3-access-point-identity-matrix.yaml&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Iceberg Table Maintenance Plan
&lt;/h2&gt;

&lt;p&gt;For production, define:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Snapshot retention period and table maintenance behavior — verify S3 Tables service-managed policies and any configurable retention settings&lt;/li&gt;
&lt;li&gt;Manifest rewrite cadence (if metadata table grows large)&lt;/li&gt;
&lt;li&gt;Orphan file cleanup policy&lt;/li&gt;
&lt;li&gt;Deduplication view or materialized latest-record table&lt;/li&gt;
&lt;li&gt;Time travel retention policy&lt;/li&gt;
&lt;li&gt;Athena engine version and Iceberg version compatibility&lt;/li&gt;
&lt;li&gt;Append-only dedup query as default named query for analysts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For operational steps, see &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/ops/iceberg-maintenance-runbook.md" rel="noopener noreferrer"&gt;&lt;code&gt;ops/iceberg-maintenance-runbook.md&lt;/code&gt;&lt;/a&gt;. For details on Iceberg spec vs S3 Tables service behavior, see &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/docs/standards-vs-service-behavior.md" rel="noopener noreferrer"&gt;&lt;code&gt;docs/standards-vs-service-behavior.md&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Iceberg does not enforce primary-key uniqueness in this PoC. Consumers should query curated latest-record views instead of the append-only base table. See &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/ops/athena-named-queries/latest_records.sql" rel="noopener noreferrer"&gt;&lt;code&gt;ops/athena-named-queries/latest_records.sql&lt;/code&gt;&lt;/a&gt; in the repo.&lt;/p&gt;

&lt;p&gt;Apache Iceberg is the open table format. Amazon S3 Tables is an AWS managed table bucket service that uses Apache Iceberg. Some operational behavior, endpoint support, and governance integration are AWS service-specific and should be validated separately from the Iceberg specification itself.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  File Identity Strategy
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;file_id method&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;th&gt;Tradeoff&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hash(volume_id + normalized_path)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;General purpose&lt;/td&gt;
&lt;td&gt;Rename = new file_id&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hash(volume_id + file_handle/inode)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rename tracking&lt;/td&gt;
&lt;td&gt;Requires inode access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Content hash (SHA-256)&lt;/td&gt;
&lt;td&gt;Immutable documents&lt;/td&gt;
&lt;td&gt;Expensive for large files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;path + last_modified + size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lightweight PoC only&lt;/td&gt;
&lt;td&gt;Fragile under overwrites&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Production should define how rename, overwrite, delete, and permission changes are represented in the metadata table.&lt;/p&gt;

&lt;p&gt;Recommended production columns: &lt;code&gt;source_system_id&lt;/code&gt;, &lt;code&gt;volume_id&lt;/code&gt;, &lt;code&gt;normalized_path&lt;/code&gt;, &lt;code&gt;path_hash&lt;/code&gt;, &lt;code&gt;content_hash&lt;/code&gt;, &lt;code&gt;scan_run_id&lt;/code&gt;, &lt;code&gt;change_type&lt;/code&gt; (created / modified / deleted / renamed / permission_changed).&lt;/p&gt;

&lt;p&gt;For FlexClone-based dev/test datasets, decide whether cloned files should retain lineage to source files. If lineage matters, store &lt;code&gt;clone_parent_volume_id&lt;/code&gt;, &lt;code&gt;clone_parent_snapshot_id&lt;/code&gt;, and &lt;code&gt;catalog_environment&lt;/code&gt; (prod / dev / test / dr). See &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/dr/snapmirror-catalog-rebinding.md" rel="noopener noreferrer"&gt;&lt;code&gt;dr/snapmirror-catalog-rebinding.md&lt;/code&gt;&lt;/a&gt; for DR failover considerations.&lt;/p&gt;

&lt;p&gt;For manufacturing and engineering workloads, see &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/schema/extensions/manufacturing_metadata.yaml" rel="noopener noreferrer"&gt;&lt;code&gt;schema/extensions/manufacturing_metadata.yaml&lt;/code&gt;&lt;/a&gt; for domain-specific metadata fields such as part number, revision, plant, machine, and inspection lot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-Tenant Deployment Considerations
&lt;/h2&gt;

&lt;p&gt;If this pattern is provided by a partner or platform team to multiple business units or customers, define the isolation boundary explicitly.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Isolation model&lt;/th&gt;
&lt;th&gt;Recommended when&lt;/th&gt;
&lt;th&gt;Tradeoff&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Table bucket per tenant&lt;/td&gt;
&lt;td&gt;Strong isolation required&lt;/td&gt;
&lt;td&gt;Higher operational overhead&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Namespace per tenant&lt;/td&gt;
&lt;td&gt;Balanced isolation and operations&lt;/td&gt;
&lt;td&gt;Shared table bucket governance required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tenant_id column in one table&lt;/td&gt;
&lt;td&gt;Internal multi-BU catalog&lt;/td&gt;
&lt;td&gt;Requires strict LF-Tags / row filters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenSearch index per tenant&lt;/td&gt;
&lt;td&gt;Search isolation required&lt;/td&gt;
&lt;td&gt;More index management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shared OpenSearch index + tenant filter&lt;/td&gt;
&lt;td&gt;Lower cost&lt;/td&gt;
&lt;td&gt;Must enforce filter in every query path&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For partner-led deployments, document tenant onboarding automation, offboarding deletion/retention policy, per-tenant cost allocation tags, and audit evidence location.&lt;/p&gt;

&lt;h2&gt;
  
  
  Business KPI Mapping
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Business problem&lt;/th&gt;
&lt;th&gt;Baseline metric&lt;/th&gt;
&lt;th&gt;Target metric&lt;/th&gt;
&lt;th&gt;How this PoC measures it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Employees cannot find documents&lt;/td&gt;
&lt;td&gt;Average search time&lt;/td&gt;
&lt;td&gt;&amp;lt; 10 sec&lt;/td&gt;
&lt;td&gt;Search latency + result relevance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manual classification is slow&lt;/td&gt;
&lt;td&gt;Files classified/day/person&lt;/td&gt;
&lt;td&gt;10x improvement&lt;/td&gt;
&lt;td&gt;AI enrichment throughput&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sensitive files are unknown&lt;/td&gt;
&lt;td&gt;% files classified for PII&lt;/td&gt;
&lt;td&gt;95%+ coverage target&lt;/td&gt;
&lt;td&gt;PII scan completion rate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Duplicate S3 copy is costly&lt;/td&gt;
&lt;td&gt;Monthly duplicate storage cost&lt;/td&gt;
&lt;td&gt;Reduce by 50%+&lt;/td&gt;
&lt;td&gt;Metadata-only architecture cost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI projects lack data inventory&lt;/td&gt;
&lt;td&gt;Dataset discovery lead time&lt;/td&gt;
&lt;td&gt;Days → hours&lt;/td&gt;
&lt;td&gt;Catalog completeness&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Business users need governed discovery&lt;/td&gt;
&lt;td&gt;% searchable assets in BI/AI tools&lt;/td&gt;
&lt;td&gt;80%+ of approved metadata visible&lt;/td&gt;
&lt;td&gt;Expose curated metadata views to Athena, Databricks, Snowflake, or BI tools&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;FSx for ONTAP prerequisites&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SVM and volume selected as catalog scope&lt;/li&gt;
&lt;li&gt;S3 Access Point attached to the target volume&lt;/li&gt;
&lt;li&gt;Associated UNIX or Windows identity documented&lt;/li&gt;
&lt;li&gt;NFS/SMB production workload impact reviewed&lt;/li&gt;
&lt;li&gt;CloudWatch metrics dashboard enabled
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone the repo&lt;/span&gt;
git clone https://github.com/Yoshiki0705/fsxn-lakehouse-integrations.git
&lt;span class="nb"&gt;cd &lt;/span&gt;fsxn-lakehouse-integrations/integrations/iceberg-metadata-catalog

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="c"&gt;# Run the demo (requires FSx for ONTAP with S3 Access Point)&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;demo/scripts
./run-demo.sh &lt;span class="nt"&gt;--ap-alias&lt;/span&gt; &amp;lt;your-ap-alias-ext-s3alias&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Don't have FSx for ONTAP?&lt;/strong&gt; You can still explore the architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/docs/en/iceberg-metadata-catalog.md" rel="noopener noreferrer"&gt;Architecture Document&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/docs/poc-results-summary.md" rel="noopener noreferrer"&gt;PoC Results Summary&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/demo/docs/demo-guide.md" rel="noopener noreferrer"&gt;Demo Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;This is Part 1 of a 3-part series:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Part 1&lt;/strong&gt; (this article): Architecture &amp;amp; PoC Results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 2&lt;/strong&gt;: AI Enrichment Pipeline — Bedrock Vision + Titan Embeddings + OpenSearch NextGen&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 3&lt;/strong&gt;: Governance &amp;amp; Cross-Platform Access — Lake Formation, PII Anonymization, Databricks/Snowflake Integration&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Don't copy data to make it searchable&lt;/strong&gt; — catalog the metadata instead. Apache Iceberg + S3 Tables gives you a managed metadata layer with time travel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Selective AI enrichment plus scale-to-zero search&lt;/strong&gt; can keep PoC and low-traffic environments cost-efficient — compute/search components idle near $0; persistent metadata and logs may incur small charges.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;42 seconds, $0.07&lt;/strong&gt; — that's the barrier to entry for an AI-powered data catalog on your existing NAS storage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start small, grow incrementally&lt;/strong&gt; — from metadata-only scan (Level 1) to full business workflow integration (Level 5). See the &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations/blob/main/integrations/iceberg-metadata-catalog/genai/production-maturity-model.md" rel="noopener noreferrer"&gt;Production Maturity Model&lt;/a&gt; for the progression path.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;em&gt;All code and documentation is available at &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/fsxn-lakehouse-integrations&lt;/a&gt;. Feedback welcome via GitHub Issues.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>iceberg</category>
      <category>datalake</category>
      <category>amazonfsxfornetappontap</category>
    </item>
    <item>
      <title>28 Industry Reference Patterns with FSx for ONTAP S3 Access Points — Phase 15</title>
      <dc:creator>Yoshiki Fujiwara(藤原 善基)@AWS Community Builder</dc:creator>
      <pubDate>Sun, 07 Jun 2026 03:00:23 +0000</pubDate>
      <link>https://dev.to/aws-builders/28-industry-reference-patterns-with-fsx-for-ontap-s3-access-points-phase-15-4g2l</link>
      <guid>https://dev.to/aws-builders/28-industry-reference-patterns-with-fsx-for-ontap-s3-access-points-phase-15-4g2l</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Phase 15 expands the pattern library from 17 to &lt;strong&gt;28 industry-specific use cases&lt;/strong&gt;, providing reference implementations across major AWS Industry verticals where FSx for ONTAP file processing is relevant. Each new pattern includes a CloudFormation template, Step Functions workflow, Python Lambda functions, 8-language documentation, and property-based tests. Combined with 6 FlexCache/FlexClone patterns and 1 SAP/ERP pattern, the repository now offers &lt;strong&gt;35 deployable reference patterns&lt;/strong&gt; for enterprise file processing on FSx for ONTAP.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The SAP/ERP pattern focuses on controlled document/report processing around ERP-adjacent file exports (IDoc, spool), not direct transactional SAP data manipulation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: These are reference implementations with production-readiness guidance, not fully certified production systems. Customers must validate against their own regulatory, security, and operational requirements before production use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For S3 standard bucket users&lt;/strong&gt;: This library is not a replacement for S3 data lake patterns. It is a file-data integration pattern for customers who want to process FSx ONTAP-resident data through S3-compatible APIs while preserving NAS access paths. See &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns/blob/main/docs/s3-bucket-user-guide.md" rel="noopener noreferrer"&gt;&lt;code&gt;docs/s3-bucket-user-guide.md&lt;/code&gt;&lt;/a&gt; for a detailed comparison.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Serverless boundary&lt;/strong&gt;: Compute (Lambda), orchestration (Step Functions), eventing (EventBridge), and AI services (Bedrock, Textract, Rekognition) are serverless/managed. FSx for ONTAP is a fully managed file system with provisioned capacity and operational considerations — it is not scale-to-zero storage. This is a &lt;strong&gt;serverless processing pattern over existing enterprise file data&lt;/strong&gt;, not a pure serverless storage pattern.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When NOT to use this&lt;/strong&gt;: If your workload is already object-native, does not require NFS/SMB coexistence, and can use standard S3 data lake patterns — prefer S3-native serverless architecture.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Repository&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why 28 Use Cases?
&lt;/h2&gt;

&lt;p&gt;AWS organizes customers into 22 industry verticals. When we mapped our existing 17 patterns against these verticals, several gaps stood out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Telecommunications&lt;/strong&gt; — No CDR/network log processing pattern&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advertising &amp;amp; Marketing&lt;/strong&gt; — No creative asset management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Travel &amp;amp; Hospitality&lt;/strong&gt; — No document processing for reservations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agriculture &amp;amp; Food&lt;/strong&gt; — No traceability or crop monitoring&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sustainability/ESG&lt;/strong&gt; — No ESG metrics extraction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nonprofit&lt;/strong&gt; — No grant management automation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Utilities&lt;/strong&gt; — No drone/SCADA-based asset inspection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real Estate&lt;/strong&gt; — No portfolio analysis&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HR&lt;/strong&gt; — No resume screening (with PII protection)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chemicals&lt;/strong&gt; — No SDS/lab notebook processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transportation&lt;/strong&gt; (railway) — No deterioration detection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Phase 15 fills all of these, covering &lt;strong&gt;19 of 22 AWS Industry verticals&lt;/strong&gt; (remaining 3 — Consumer Packaged Goods, Mining, Software/Internet — have limited file-processing relevance for this pattern type). Combined with 11 Japan-market focus areas (all covered), the repository addresses the vast majority of enterprise file processing scenarios.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 11 New Patterns
&lt;/h2&gt;

&lt;h3&gt;
  
  
  P0: Foundation Patterns
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;UC&lt;/th&gt;
&lt;th&gt;Industry&lt;/th&gt;
&lt;th&gt;Key AWS Services&lt;/th&gt;
&lt;th&gt;Differentiator&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;UC18&lt;/td&gt;
&lt;td&gt;Telecom&lt;/td&gt;
&lt;td&gt;Athena, Bedrock&lt;/td&gt;
&lt;td&gt;CDR/syslog anomaly detection with 7-day baseline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UC19&lt;/td&gt;
&lt;td&gt;AdTech&lt;/td&gt;
&lt;td&gt;Rekognition, Textract, Bedrock&lt;/td&gt;
&lt;td&gt;Brand compliance scoring + moderation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  P1: Document Intelligence
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;UC&lt;/th&gt;
&lt;th&gt;Industry&lt;/th&gt;
&lt;th&gt;Key AWS Services&lt;/th&gt;
&lt;th&gt;Differentiator&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;UC20&lt;/td&gt;
&lt;td&gt;Travel&lt;/td&gt;
&lt;td&gt;Textract, Comprehend, Rekognition&lt;/td&gt;
&lt;td&gt;Multilingual reservation extraction + facility inspection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UC21&lt;/td&gt;
&lt;td&gt;Agriculture&lt;/td&gt;
&lt;td&gt;Rekognition, Textract, Bedrock&lt;/td&gt;
&lt;td&gt;GeoTIFF crop analysis + lot traceability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UC22&lt;/td&gt;
&lt;td&gt;Transportation&lt;/td&gt;
&lt;td&gt;Rekognition, Textract, Bedrock&lt;/td&gt;
&lt;td&gt;Safety-critical escalation trigger + deterioration trends&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  P2: Specialized Processing
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;UC&lt;/th&gt;
&lt;th&gt;Industry&lt;/th&gt;
&lt;th&gt;Key AWS Services&lt;/th&gt;
&lt;th&gt;Differentiator&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;UC23&lt;/td&gt;
&lt;td&gt;Sustainability&lt;/td&gt;
&lt;td&gt;Textract, Bedrock&lt;/td&gt;
&lt;td&gt;ESG metric extraction + GRI/TCFD/ISSB mapping&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UC24&lt;/td&gt;
&lt;td&gt;Nonprofit&lt;/td&gt;
&lt;td&gt;Textract, Comprehend, Bedrock&lt;/td&gt;
&lt;td&gt;Grant application + outcome matching&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UC25&lt;/td&gt;
&lt;td&gt;Utilities&lt;/td&gt;
&lt;td&gt;Rekognition, Bedrock, Athena&lt;/td&gt;
&lt;td&gt;Drone + SCADA + thermal tri-modal inspection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UC26&lt;/td&gt;
&lt;td&gt;Real Estate&lt;/td&gt;
&lt;td&gt;Rekognition, Textract, Bedrock&lt;/td&gt;
&lt;td&gt;Property analysis + lease extraction + PII flagging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UC27&lt;/td&gt;
&lt;td&gt;HR&lt;/td&gt;
&lt;td&gt;Textract, Comprehend, Bedrock&lt;/td&gt;
&lt;td&gt;Recruiting document triage with PII protection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UC28&lt;/td&gt;
&lt;td&gt;Chemicals&lt;/td&gt;
&lt;td&gt;Textract, Rekognition, Bedrock&lt;/td&gt;
&lt;td&gt;SDS hazard extraction + GHS compliance + lab notebook&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Architecture: One Pattern, Many Industries
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Architecture Classification
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Classification&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Workflow orchestration&lt;/td&gt;
&lt;td&gt;Serverless (Step Functions)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compute&lt;/td&gt;
&lt;td&gt;Serverless (Lambda)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Eventing / scheduling&lt;/td&gt;
&lt;td&gt;Serverless (EventBridge)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI/ML services&lt;/td&gt;
&lt;td&gt;Managed service consumption (Bedrock, Textract, Rekognition, Comprehend)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File storage&lt;/td&gt;
&lt;td&gt;Managed/provisioned (FSx for ONTAP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Operations model&lt;/td&gt;
&lt;td&gt;Hybrid: serverless processing + managed file storage&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Lambda concurrency must be bounded by FSx ONTAP S3 AP throughput behavior. Do not treat Lambda concurrency as the only scaling control.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Common Workflow Pattern
&lt;/h3&gt;

&lt;p&gt;Every pattern follows the same proven architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EventBridge Scheduler
       │
       ▼
Step Functions State Machine
       │
       ├── Discovery Lambda (VPC-internal, ONTAP API)
       │        │
       │        ▼
       │   S3 Access Point (list + classify files)
       │
       ├── Processing Map (parallel, Retry + Catch)
       │        │
       │        ▼
       │   [Rekognition | Textract | Comprehend | Bedrock | Athena]
       │
       └── Report Lambda
                │
                ├── Output → S3 AP (FSx ONTAP volume)
                └── SNS Notification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What changes per industry:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;File prefixes and extensions&lt;/strong&gt; (Discovery Lambda configuration)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI/ML service selection&lt;/strong&gt; (Rekognition for images, Textract for documents, Bedrock for reasoning)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Domain-specific schemas&lt;/strong&gt; (ESG metrics, GHS sections, CDR fields)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review thresholds&lt;/strong&gt; (60% escalation trigger for safety-critical defects, 80% standard detection, 90% auto-approve threshold)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance requirements&lt;/strong&gt; (PII filtering for HR, data classification labels, audit trails)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For production deployments, validate how S3 AP-generated output files appear from existing NFS/SMB clients, including ownership, permissions, naming convention, and Snapshot/SnapMirror policy impact. See &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns/blob/main/docs/ontap-integration-notes.md" rel="noopener noreferrer"&gt;ONTAP Integration Notes&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Shared Modules: The Productivity Multiplier
&lt;/h2&gt;

&lt;p&gt;The 11 new patterns reuse the same &lt;code&gt;shared/&lt;/code&gt; modules that power the original 17:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Module&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Used By&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;s3ap_helper.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;S3 Access Point abstraction (alias + ARN)&lt;/td&gt;
&lt;td&gt;All 28 UCs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;exceptions.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Domain exceptions + error handler decorator&lt;/td&gt;
&lt;td&gt;All 28 UCs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;observability.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;EMF metrics + structured logging&lt;/td&gt;
&lt;td&gt;All 28 UCs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;human_review.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Confidence-based review decisions&lt;/td&gt;
&lt;td&gt;UC22, UC25, UC27&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;data_classification.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Output data labeling (INTERNAL/CUI/etc.)&lt;/td&gt;
&lt;td&gt;UC23, UC24, UC27, UC28&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;schemas/events.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TypedDict event/response schemas&lt;/td&gt;
&lt;td&gt;All 28 UCs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Adding a new industry pattern takes &lt;strong&gt;2-3 hours&lt;/strong&gt; (not days) because the infrastructure is already solved. A new pattern is considered field-shareable only after DemoMode execution, cfn-lint validation, unit/property tests, success metrics, data classification, and human review thresholds are documented.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Design Decisions for New Patterns
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Safety-Critical Thresholds (UC22)
&lt;/h3&gt;

&lt;p&gt;Railway infrastructure inspection cannot accept false negatives. We use a &lt;strong&gt;dual-threshold&lt;/strong&gt; approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;STANDARD_THRESHOLD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;       &lt;span class="c1"&gt;# General defect detection trigger
&lt;/span&gt;&lt;span class="n"&gt;SAFETY_CRITICAL_THRESHOLD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;  &lt;span class="c1"&gt;# Bridges, signaling, rail joints — lower to reduce false negatives
&lt;/span&gt;&lt;span class="n"&gt;HUMAN_REVIEW_THRESHOLD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;    &lt;span class="c1"&gt;# Auto-approve only above this
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Critical design intent&lt;/strong&gt;: 60% is NOT an auto-approval threshold. It is an &lt;strong&gt;escalation trigger&lt;/strong&gt; — any signal above 60% for safety-critical categories triggers mandatory human review. The system is designed to surface potential defects for expert evaluation, not to automate safety decisions. All detections below 90% confidence require human review regardless of category.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. PII-First Design (UC27)
&lt;/h3&gt;

&lt;p&gt;Recruiting document triage handles personal data. The pattern enforces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No PII in logs&lt;/strong&gt; — structured logging strips personal identifiers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protected characteristic exclusion&lt;/strong&gt; — Bedrock prompt explicitly excludes age, gender, ethnicity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encrypted output&lt;/strong&gt; — all results written with data classification labels&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit trail&lt;/strong&gt; — every scoring decision is logged with justification (not content)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Regulatory notice&lt;/strong&gt;: UC27 is a &lt;strong&gt;document triage and summarization workflow&lt;/strong&gt;, not an automated hiring decision system. Final hiring decisions must remain with qualified human reviewers. Customers must validate against local labor law, privacy regulations (GDPR, APPI, CCPA), and anti-discrimination requirements before any use in recruitment processes. Output must not include ranking by protected attributes, and explanation fields must cite only job-relevant qualifications.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  3. Tri-Modal Inspection (UC25)
&lt;/h3&gt;

&lt;p&gt;Utilities asset inspection combines three data modalities in a single workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Visual&lt;/strong&gt; (drone images) → Rekognition defect detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporal&lt;/strong&gt; (SCADA logs) → Athena time-series anomaly detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thermal&lt;/strong&gt; (FLIR images) → Hot-spot classification (≥10°C differential)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Step Functions workflow processes all three in parallel Map states, then merges results for a unified maintenance priority report.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. ESG Framework Mapping (UC23)
&lt;/h3&gt;

&lt;p&gt;Sustainability reporting requires mapping extracted metrics to multiple frameworks simultaneously:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GRI&lt;/strong&gt; (Global Reporting Initiative)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TCFD&lt;/strong&gt; (Task Force on Climate-related Financial Disclosures)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ISSB&lt;/strong&gt; (International Sustainability Standards Board)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bedrock performs the mapping using structured prompts with framework-specific indicator definitions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Testing: 1,499+ Tests Across 28 Patterns
&lt;/h2&gt;

&lt;p&gt;Each new pattern includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unit tests&lt;/strong&gt; with moto for AWS service mocking&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Property-based tests&lt;/strong&gt; (Hypothesis) for invariant verification&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cfn-lint validation&lt;/strong&gt; for all CloudFormation templates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ruff linting&lt;/strong&gt; for Python code quality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notable property tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UC22: &lt;code&gt;severity_level ∈ {critical, major, minor, observation}&lt;/code&gt; for all inputs&lt;/li&gt;
&lt;li&gt;UC25: SCADA thresholds within physical bounds (voltage ±5%, frequency ±0.5 Hz)&lt;/li&gt;
&lt;li&gt;UC27: No protected characteristics appear in any output field&lt;/li&gt;
&lt;li&gt;UC28: All GHS mandatory sections validated for completeness&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Responsible AI and Human Review
&lt;/h2&gt;

&lt;p&gt;These patterns are &lt;strong&gt;reference workflows&lt;/strong&gt;, not fully automated decision systems. For regulated or safety-critical domains (healthcare, finance, transportation, HR, public sector), customers must define:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Human review thresholds&lt;/strong&gt; — what confidence level requires expert validation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Appeal/escalation process&lt;/strong&gt; — how incorrect classifications are corrected&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit trail requirements&lt;/strong&gt; — what decisions need immutable logging&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data retention policy&lt;/strong&gt; — how long intermediate results are kept&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model evaluation criteria&lt;/strong&gt; — accuracy, hallucination rate, bias testing on domain data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local regulatory review&lt;/strong&gt; — jurisdiction-specific compliance (FISC, HIPAA, GDPR, NARA, labor law)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;shared/human_review.py&lt;/code&gt; module provides a framework for confidence-based routing, but &lt;strong&gt;threshold values and escalation procedures must be defined by domain experts&lt;/strong&gt;, not by template defaults.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Customers are responsible for validating these workflows against their own policies, risk classification, and regulatory obligations before production use.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Pattern Selection Guide
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Customer Situation&lt;/th&gt;
&lt;th&gt;Recommended Starting Pattern&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FSx ONTAP already used for shared files&lt;/td&gt;
&lt;td&gt;UC by industry + DemoMode=false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No FSx ONTAP yet, wants to evaluate workflow&lt;/td&gt;
&lt;td&gt;Any UC + DemoMode=true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Document-heavy workload (PDF, contracts, reports)&lt;/td&gt;
&lt;td&gt;UC20 / UC23 / UC24 / UC26 / UC27 / UC28&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image-heavy inspection workload&lt;/td&gt;
&lt;td&gt;UC19 / UC21 / UC22 / UC25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logs / time-series / analytics workload&lt;/td&gt;
&lt;td&gt;UC18 / UC25 (SCADA)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Safety-critical review required&lt;/td&gt;
&lt;td&gt;UC22 / UC25 with human_review module&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PII-sensitive workflow&lt;/td&gt;
&lt;td&gt;UC27 / UC26 with data_classification module&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESG / sustainability reporting&lt;/td&gt;
&lt;td&gt;UC23 with framework mapping&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Greenfield object-native workload (no NAS)&lt;/td&gt;
&lt;td&gt;Prefer standard S3 + serverless-native architecture&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  DemoMode to Production Path
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Area&lt;/th&gt;
&lt;th&gt;DemoMode (evaluation)&lt;/th&gt;
&lt;th&gt;Production (FSx ONTAP)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Input source&lt;/td&gt;
&lt;td&gt;Regular S3 bucket&lt;/td&gt;
&lt;td&gt;FSx ONTAP S3 Access Point&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Permissions&lt;/td&gt;
&lt;td&gt;S3 IAM only&lt;/td&gt;
&lt;td&gt;IAM + S3 AP policy + ONTAP file identity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;Public AWS service path&lt;/td&gt;
&lt;td&gt;Internet-origin or VPC-origin design decision (&lt;strong&gt;NetworkOrigin is immutable after creation&lt;/strong&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data&lt;/td&gt;
&lt;td&gt;Sample/synthetic data&lt;/td&gt;
&lt;td&gt;Customer-controlled NAS data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Governance&lt;/td&gt;
&lt;td&gt;Demo labels only&lt;/td&gt;
&lt;td&gt;Data classification + lineage + retention&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost&lt;/td&gt;
&lt;td&gt;~$0.10/execution&lt;/td&gt;
&lt;td&gt;+ FSx ONTAP infrastructure (~$194/month base)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code compatibility&lt;/td&gt;
&lt;td&gt;Standard S3 bucket semantics&lt;/td&gt;
&lt;td&gt;Validate the FSx ONTAP S3 AP API subset and unsupported S3 bucket features before production&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access point lifecycle&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;NetworkOrigin changes require creating a new S3 AP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Cost varies by region, deployment type, SSD capacity, throughput capacity, backups, and data transfer; the figure above is a baseline estimate for Single-AZ / 128 MBps / 1 TB SSD. This cost model is not scale-to-zero storage. Use this pattern when the value of processing existing NAS data in place outweighs the baseline FSx ONTAP infrastructure cost.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Deployment: 30 Minutes to First Result
&lt;/h2&gt;

&lt;p&gt;Every pattern includes a &lt;code&gt;samconfig.toml.example&lt;/code&gt; and step-by-step deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Copy and configure&lt;/span&gt;
&lt;span class="nb"&gt;cp &lt;/span&gt;samconfig.toml.example samconfig.toml
&lt;span class="c"&gt;# Edit: S3AccessPointAlias, VpcId, SubnetIds, etc.&lt;/span&gt;

&lt;span class="c"&gt;# 2. Deploy&lt;/span&gt;
sam build &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sam deploy &lt;span class="nt"&gt;--guided&lt;/span&gt;

&lt;span class="c"&gt;# 3. Execute&lt;/span&gt;
aws stepfunctions start-execution &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--state-machine-arn&lt;/span&gt; &amp;lt;ARN from outputs&amp;gt;

&lt;span class="c"&gt;# 4. Verify&lt;/span&gt;
aws stepfunctions describe-execution &lt;span class="nt"&gt;--execution-arn&lt;/span&gt; &amp;lt;ARN&amp;gt;
&lt;span class="c"&gt;# Status: SUCCEEDED&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For patterns without FSx for ONTAP, &lt;strong&gt;DemoMode=true&lt;/strong&gt; uses a regular S3 bucket — ideal for evaluation without infrastructure commitment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Benchmark Insight: Small Files Don't Need More Throughput
&lt;/h2&gt;

&lt;p&gt;During Phase 15 deployment verification, we ran benchmarks at 128/256/512 MBps throughput capacity with a 202-byte JSON manifest:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Throughput&lt;/th&gt;
&lt;th&gt;P50 @ conc=1&lt;/th&gt;
&lt;th&gt;P50 @ conc=25&lt;/th&gt;
&lt;th&gt;P50 @ conc=50&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;256 MBps&lt;/td&gt;
&lt;td&gt;56.9 ms&lt;/td&gt;
&lt;td&gt;60.3 ms&lt;/td&gt;
&lt;td&gt;257.9 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;512 MBps&lt;/td&gt;
&lt;td&gt;59.8 ms&lt;/td&gt;
&lt;td&gt;59.9 ms&lt;/td&gt;
&lt;td&gt;246.1 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;: For metadata-heavy workloads (JSON manifests, small config files, document headers), throughput capacity increase has zero effect on latency. The bottleneck is connection overhead (TLS + S3 AP routing), not bandwidth. Save costs by staying at 128 MBps for these workloads.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sizing reference from a specific test environment, not a service limit.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Documentation: 8 Languages × 28 Patterns
&lt;/h2&gt;

&lt;p&gt;Every pattern includes documentation in:&lt;br&gt;
🇯🇵 Japanese (primary) · 🇺🇸 English · 🇰🇷 Korean · 🇨🇳 Chinese (Simplified) · 🇹🇼 Chinese (Traditional) · 🇫🇷 French · 🇩🇪 German · 🇪🇸 Spanish&lt;/p&gt;

&lt;p&gt;Each language includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;README.md&lt;/code&gt; — Overview, deployment, success metrics&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docs/architecture.md&lt;/code&gt; — Mermaid data flow diagram&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docs/demo-guide.md&lt;/code&gt; — Step-by-step demo with verification checklist&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each UC README includes &lt;strong&gt;Success Metrics&lt;/strong&gt; with Business Outcome, Technical KPI, Quality KPI, Cost KPI, and Go/No-Go criteria. This article summarizes the portfolio; detailed success criteria live with each pattern.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Changed Since Phase 14
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Phase 14&lt;/th&gt;
&lt;th&gt;Phase 15&lt;/th&gt;
&lt;th&gt;Delta&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Use cases&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;+11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total patterns&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;td&gt;+11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test count&lt;/td&gt;
&lt;td&gt;~800&lt;/td&gt;
&lt;td&gt;1,499+&lt;/td&gt;
&lt;td&gt;+699&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Industries covered&lt;/td&gt;
&lt;td&gt;14/22&lt;/td&gt;
&lt;td&gt;19/22&lt;/td&gt;
&lt;td&gt;+5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Languages&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shared modules&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;+3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Documentation files&lt;/td&gt;
&lt;td&gt;~400&lt;/td&gt;
&lt;td&gt;~700&lt;/td&gt;
&lt;td&gt;+300&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Who Should Use Each New Pattern?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Recommended Starting Patterns
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Start here if...&lt;/th&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;You want document intelligence&lt;/td&gt;
&lt;td&gt;UC20 or UC26&lt;/td&gt;
&lt;td&gt;Multilingual extraction + property/lease analysis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You want log analytics&lt;/td&gt;
&lt;td&gt;UC18&lt;/td&gt;
&lt;td&gt;CDR/syslog anomaly detection with baseline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You need PII-safe document triage&lt;/td&gt;
&lt;td&gt;UC27&lt;/td&gt;
&lt;td&gt;Protected characteristic exclusion built-in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You need inspection workflows&lt;/td&gt;
&lt;td&gt;UC22 or UC25&lt;/td&gt;
&lt;td&gt;Safety-critical escalation + tri-modal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You want ESG extraction&lt;/td&gt;
&lt;td&gt;UC23&lt;/td&gt;
&lt;td&gt;Multi-framework mapping (GRI/TCFD/ISSB)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Full Pattern List
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;If you are...&lt;/th&gt;
&lt;th&gt;Start with...&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Telecom operator with CDR data&lt;/td&gt;
&lt;td&gt;UC18&lt;/td&gt;
&lt;td&gt;Anomaly detection across network logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ad agency managing creative assets&lt;/td&gt;
&lt;td&gt;UC19&lt;/td&gt;
&lt;td&gt;Automated brand compliance scoring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hotel chain with inspection photos&lt;/td&gt;
&lt;td&gt;UC20&lt;/td&gt;
&lt;td&gt;Facility condition monitoring at scale&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agricultural cooperative&lt;/td&gt;
&lt;td&gt;UC21&lt;/td&gt;
&lt;td&gt;Crop health + traceability in one workflow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Railway/transit operator&lt;/td&gt;
&lt;td&gt;UC22&lt;/td&gt;
&lt;td&gt;Safety-critical deterioration detection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESG reporting team&lt;/td&gt;
&lt;td&gt;UC23&lt;/td&gt;
&lt;td&gt;Multi-framework metric extraction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grant-making foundation&lt;/td&gt;
&lt;td&gt;UC24&lt;/td&gt;
&lt;td&gt;Application processing + outcome matching&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Power utility with drone programs&lt;/td&gt;
&lt;td&gt;UC25&lt;/td&gt;
&lt;td&gt;Tri-modal inspection (visual + SCADA + thermal)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real estate portfolio manager&lt;/td&gt;
&lt;td&gt;UC26&lt;/td&gt;
&lt;td&gt;Property analysis + lease extraction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recruiting team (APAC/EMEA)&lt;/td&gt;
&lt;td&gt;UC27&lt;/td&gt;
&lt;td&gt;PII-compliant recruiting document triage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chemical manufacturer&lt;/td&gt;
&lt;td&gt;UC28&lt;/td&gt;
&lt;td&gt;SDS compliance + lab notebook digitization&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;VPC-internal Lambda benchmark&lt;/strong&gt; — True VPC path performance (eliminates Internet latency)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FPolicy TCP-level Replay Storm&lt;/strong&gt; — Real ONTAP event replay (requires ECS rebuild)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-repository integration&lt;/strong&gt; — Link patterns to &lt;a href="https://github.com/Yoshiki0705/fsxn-lakehouse-integrations" rel="noopener noreferrer"&gt;fsxn-lakehouse-integrations&lt;/a&gt; for analytics pipelines&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Glue Data Catalog integration&lt;/strong&gt; — Schema versioning and data quality checks for output datasets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community contributions&lt;/strong&gt; — Pattern template for community-submitted industry use cases&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Resolved from Phase 14&lt;/strong&gt;: FlexCache × S3 AP integration confirmed as not currently supported by AWS — tracked in Field Feedback Log. FC1 Recovery Metrics depend on this feature. Both remain pending AWS feature availability.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Ownership Model
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Recommended Owner&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Shared modules (&lt;code&gt;shared/&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Platform / DevOps team&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UC business logic (&lt;code&gt;functions/&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Application / data team&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FSx ONTAP and S3 AP infrastructure&lt;/td&gt;
&lt;td&gt;Storage / platform team&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IAM, data classification, encryption&lt;/td&gt;
&lt;td&gt;Security team&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Success metrics and Go/No-Go&lt;/td&gt;
&lt;td&gt;Business owner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Regulatory compliance mapping&lt;/td&gt;
&lt;td&gt;GRC / legal team&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Compliance Positioning
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;These templates &lt;strong&gt;do not certify compliance&lt;/strong&gt; with any specific regulation. They provide implementation hooks for audit logging, retention, classification, and human review that customers can map to their regulatory controls. Each organization must independently validate compliance with applicable regulations (FISC, HIPAA, GDPR, NARA, local labor law, etc.).&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  NetApp / ONTAP Operational Notes
&lt;/h2&gt;

&lt;p&gt;For production deployments on FSx for ONTAP, review the ONTAP-specific guidance in &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns/blob/main/docs/ontap-integration-notes.md" rel="noopener noreferrer"&gt;&lt;code&gt;docs/ontap-integration-notes.md&lt;/code&gt;&lt;/a&gt;, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SVM / volume / protocol scope assumptions&lt;/li&gt;
&lt;li&gt;NFS/SMB visibility of S3 AP-generated outputs (file ownership = AP file system identity)&lt;/li&gt;
&lt;li&gt;IAM + S3 AP policy + ONTAP file identity behavior, separate from NFS export policy evaluation&lt;/li&gt;
&lt;li&gt;Snapshot / SnapMirror / retention impact on output artifacts&lt;/li&gt;
&lt;li&gt;Scheduler vs FPolicy trigger mode selection&lt;/li&gt;
&lt;li&gt;FlexCache / FlexClone combination patterns per UC&lt;/li&gt;
&lt;li&gt;NetApp support diagnostic bundle&lt;/li&gt;
&lt;li&gt;OT/manufacturing safety caveat&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;FlexCache/FlexClone note&lt;/strong&gt;: UC × FC combination patterns describe adjacent architecture patterns. Validate current AWS/FSx feature support before assuming direct S3 AP access to cached or cloned paths.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benchmark scope&lt;/strong&gt;: Results are from Single-AZ, First-generation FSx ONTAP. Validate separately for Multi-AZ or newer generation file systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Regulated research workflows&lt;/strong&gt; (UC7, UC28, FC5): Capture input dataset version, model/prompt version, reviewer action, and output checksum as lineage metadata. See &lt;code&gt;shared/lineage.py&lt;/code&gt; v2 fields.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Stats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;New patterns&lt;/strong&gt;: 11 (UC18-UC28)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New Lambda functions&lt;/strong&gt;: 44 (4 per pattern average)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New tests&lt;/strong&gt;: 699&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New documentation files&lt;/strong&gt;: ~300 (across 8 languages)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New shared modules&lt;/strong&gt;: &lt;code&gt;data_classification.py&lt;/code&gt;, &lt;code&gt;human_review.py&lt;/code&gt;, &lt;code&gt;schemas/events.py&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment verified&lt;/strong&gt;: All 28 UCs achieved SUCCEEDED status in ap-northeast-1&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Benchmark runs&lt;/strong&gt;: 2 additional (256/512 MBps small-file comparison)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost&lt;/strong&gt;: ~$10 total for deployment verification (Lambda + Step Functions + Bedrock Nova Lite)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Try It Today
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns.git
&lt;span class="nb"&gt;cd &lt;/span&gt;FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns

&lt;span class="c"&gt;# Quick test (no AWS account needed)&lt;/span&gt;
make test-quick

&lt;span class="c"&gt;# Deploy any pattern with DemoMode (no FSx ONTAP needed)&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;telecom-network-analytics
&lt;span class="nb"&gt;cp &lt;/span&gt;samconfig.toml.example samconfig.toml
sam build &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sam deploy &lt;span class="nt"&gt;--guided&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;Repository&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full series&lt;/strong&gt;: &lt;a href="https://dev.to/yoshikifujiwara/series/39652"&gt;FSx for ONTAP S3 Access Points on DEV.to&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>amazonfsxfornetappontap</category>
      <category>s3accesspoints</category>
    </item>
    <item>
      <title>Evidence Expansion, Presigned URL Discovery, and Operational Surprises — FSx for ONTAP S3 Access Points, Phase 14</title>
      <dc:creator>Yoshiki Fujiwara(藤原 善基)@AWS Community Builder</dc:creator>
      <pubDate>Sun, 07 Jun 2026 02:53:08 +0000</pubDate>
      <link>https://dev.to/aws-builders/evidence-expansion-presigned-url-discovery-and-operational-surprises-fsx-for-ontap-s3-access-514o</link>
      <guid>https://dev.to/aws-builders/evidence-expansion-presigned-url-discovery-and-operational-surprises-fsx-for-ontap-s3-access-514o</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Phase 14 shifts from building patterns to &lt;strong&gt;hardening the evidence base&lt;/strong&gt;. After publishing Phase 13's field-ready reference architecture, I focused on post-publication refinement: Partner/SI delivery assets, benchmark methodology standardization, S3 AP compatibility clarification (Presigned URLs work despite documentation), and an unexpected operational discovery — S3 Access Points become unavailable during FSx throughput capacity changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repository&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Phase 14?
&lt;/h2&gt;

&lt;p&gt;Phase 13 delivered the field-ready baseline. Phase 14 answers the question: &lt;strong&gt;"Now that the patterns exist, how do we make them easier to evaluate, adopt, and operate?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The work falls into four categories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Partner/SI delivery acceleration&lt;/strong&gt; — one-pager, improved PoC templates, FC1-FC6 conversation starters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Benchmark methodology&lt;/strong&gt; — standardized run IDs, hypothesis-driven testing, Range GET plans&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatibility clarification&lt;/strong&gt; — Presigned URL behavior confirmed with AWS Support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operational discovery&lt;/strong&gt; — S3 AP unavailability during throughput capacity changes&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Partner/SI One-Pager: What / When / How / Where
&lt;/h2&gt;

&lt;p&gt;Partners and SIs told us the existing 7-step delivery checklist was comprehensive but too long for a first conversation. Phase 14 adds a &lt;strong&gt;single-page overview&lt;/strong&gt; that answers four questions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Section&lt;/th&gt;
&lt;th&gt;Content&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;What&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;28 UCs + 6 FC patterns, CloudFormation templates, 4-level maturity model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;When&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Customer has FSx for ONTAP + needs serverless file processing + permission-aware access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;How&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Identify UC → Deploy template → Measure baseline → Evaluate Go/No-Go&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Where&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Links to Success Metrics, Governance, Production Readiness, Benchmarks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Available in both &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns/blob/main/docs/partner-si-one-pager.md" rel="noopener noreferrer"&gt;Japanese&lt;/a&gt; and &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns/blob/main/docs/partner-si-one-pager.en.md" rel="noopener noreferrer"&gt;English&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  FC1-FC6 Recommended First Questions
&lt;/h3&gt;

&lt;p&gt;Each FlexCache/FlexClone pattern now has a &lt;strong&gt;recommended first conversation question&lt;/strong&gt; — the question a Partner/SI should ask to determine if the pattern is relevant:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;First Question&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FC1 (Anycast/DR)&lt;/td&gt;
&lt;td&gt;"What is your current read latency from remote sites, and what target would justify a caching layer?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FC2 (Render)&lt;/td&gt;
&lt;td&gt;"How many concurrent render jobs share the same source data, and what is the job lifecycle?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FC3 (RAG)&lt;/td&gt;
&lt;td&gt;"Which file shares contain the knowledge base, and do access permissions need to be preserved in RAG results?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FC4 (CAE)&lt;/td&gt;
&lt;td&gt;"What is the typical solver output size and how quickly must results be available for post-processing?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FC5 (Life Sciences)&lt;/td&gt;
&lt;td&gt;"How do you currently share research datasets between teams while maintaining data governance?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FC6 (Gaming)&lt;/td&gt;
&lt;td&gt;"What is your current build pipeline duration and which asset validation steps are bottlenecks?"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  2. Presigned URLs: "Not Supported" but Working
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Production Warning&lt;/strong&gt;: AWS Support explicitly states that operations marked "Not supported" should NOT be relied upon for production workloads, even when they return success today. The behavior may change without deprecation notice, return inconsistent results across regions, or stop working after service updates. &lt;strong&gt;Design alternatives for any workflow that requires presigned URL access to FSx for ONTAP S3 Access Points.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The Discovery
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://docs.aws.amazon.com/fsx/latest/ONTAPGuide/access-points-for-fsxn-object-api-support.html" rel="noopener noreferrer"&gt;FSx for ONTAP S3 AP compatibility table&lt;/a&gt; lists &lt;code&gt;Presign — Not supported&lt;/code&gt;. However, testing showed presigned URLs for GetObject work successfully.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Support Clarification
&lt;/h3&gt;

&lt;p&gt;After raising this with AWS Support, the explanation was clear:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Presigning is client-side only&lt;/strong&gt; — &lt;code&gt;aws s3 presign&lt;/code&gt; computes a SigV4 signature locally. No network request is made.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The presigned URL executes a standard GetObject&lt;/strong&gt; — signature is in query parameters instead of the Authorization header.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Since GetObject is Supported, presigned URLs cannot be blocked&lt;/strong&gt; without breaking GetObject itself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The documentation likely intended&lt;/strong&gt; to indicate that presigned URL workflows are not officially tested.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Production Guidance
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;Guidance&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GetObject, PutObject, ListObjectsV2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Supported&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Build on freely&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Conditional writes (If-None-Match)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Blocked&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Returns NotImplemented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Presigned URLs&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Not supported (doc)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Works but do not rely on for production&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;AWS Support has escalated documentation clarification to the FSx for ONTAP service team. The distinction between "Not supported + hard-blocked" (returns error) and "Not supported + may incidentally work" (no guarantees) is being reviewed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Readers should verify the &lt;a href="https://docs.aws.amazon.com/fsx/latest/ONTAPGuide/access-points-for-fsxn-object-api-support.html" rel="noopener noreferrer"&gt;latest AWS documentation&lt;/a&gt; before relying on this behavior, as the status may change.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Alternatives to Presigned URLs
&lt;/h3&gt;

&lt;p&gt;If you need time-limited or delegated file access without relying on unsupported behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API Gateway + Lambda proxy&lt;/strong&gt; with IAM or JWT authorization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudFront signed URLs&lt;/strong&gt; backed by a controlled Lambda@Edge origin&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporary STS credentials&lt;/strong&gt; with scoped IAM permissions (time-limited, per-object or prefix)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application-level download broker&lt;/strong&gt; with audit logging and access revocation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a broader comparison with standard S3 bucket semantics, see the &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns/blob/main/docs/s3-bucket-user-guide.md" rel="noopener noreferrer"&gt;S3 Bucket User Guide&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Benchmark Methodology: Hypothesis-Driven Testing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why 1769 MB Lambda Memory?
&lt;/h3&gt;

&lt;p&gt;Lambda memory directly controls CPU and network bandwidth allocation. At 1769 MB, Lambda receives exactly 1 vCPU equivalent, providing consistent and reproducible network throughput for benchmark measurements. Lower memory settings would introduce variable network bandwidth as a confounding factor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benchmark Run ID Convention
&lt;/h3&gt;

&lt;p&gt;Every benchmark run now follows a standardized format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;s3ap-bench-{YYYY-MM-DD}-{seq}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With mandatory fixed conditions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ap-northeast-1&lt;/span&gt;
&lt;span class="na"&gt;Lambda memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1769 MB (1 vCPU)&lt;/span&gt;
&lt;span class="na"&gt;Lambda architecture&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arm64&lt;/span&gt;
&lt;span class="na"&gt;FSx Throughput Capacity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;128 / 256 / 512&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt; &lt;span class="s"&gt;MBps&lt;/span&gt;
&lt;span class="na"&gt;Iterations per data point&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;
&lt;span class="na"&gt;Statistics&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;p50, p90, p95, p99, min, max&lt;/span&gt;
&lt;span class="na"&gt;Concurrent NFS/SMB workload&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;None / Light / Production-level&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Hypothesis: Throughput Capacity vs Practical Concurrency Point
&lt;/h3&gt;

&lt;p&gt;Based on 128 MBps observations where I observed concurrency=10 as the practical upper limit &lt;strong&gt;in this specific test environment&lt;/strong&gt; (1 MB objects, single Lambda invocation pattern, no concurrent NFS/SMB workload), I hypothesize:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Practical concurrency point may shift with FSx throughput capacity increase.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;FSx Capacity&lt;/th&gt;
&lt;th&gt;Predicted Practical Concurrency&lt;/th&gt;
&lt;th&gt;Rationale&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;128 MBps&lt;/td&gt;
&lt;td&gt;10 (observed)&lt;/td&gt;
&lt;td&gt;Baseline — P99 exceeded 420 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;256 MBps&lt;/td&gt;
&lt;td&gt;~15-25&lt;/td&gt;
&lt;td&gt;Sub-linear scaling is plausible due to ONTAP WAFL overhead and TCP connection management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;512 MBps&lt;/td&gt;
&lt;td&gt;~25-45&lt;/td&gt;
&lt;td&gt;Step-function behavior possible if a different bottleneck emerges&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Linear scaling (2x capacity = 2x concurrency) is one possible outcome, but sub-linear or step-function behavior is equally plausible. The actual relationship depends on ONTAP data plane queuing, TCP connection overhead, and whether the bottleneck shifts from throughput to IOPS or latency at higher capacities.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Initial verification was blocked by the S3 AP issue described below. Results were published after recovery on 2026-05-25.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update (2026-05-25)&lt;/strong&gt;: S3 AP recovered. Benchmarks completed. See Section 7 for results and hypothesis verification.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  4. Operational Discovery: S3 AP Unavailability During Throughput Changes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Happened
&lt;/h3&gt;

&lt;p&gt;While preparing to run 256 MBps benchmarks, I changed the FSx throughput capacity from 128 to 256 MBps. After the change completed successfully:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;All S3 Access Points&lt;/strong&gt; on the file system returned &lt;code&gt;ServiceUnavailable&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All SVMs&lt;/strong&gt; were affected (not just one)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reverting to 128 MBps&lt;/strong&gt; did not immediately restore S3 AP access&lt;/li&gt;
&lt;li&gt;The file system itself remained &lt;code&gt;AVAILABLE&lt;/code&gt; throughout&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Timeline
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;T+0&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;update-file-system&lt;/code&gt; ThroughputCapacity 128 → 256&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T+25 min&lt;/td&gt;
&lt;td&gt;Change completed (256 MBps confirmed)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T+25+ min&lt;/td&gt;
&lt;td&gt;All S3 APs return ServiceUnavailable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T+40 min&lt;/td&gt;
&lt;td&gt;Revert initiated (256 → 128)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T+65 min&lt;/td&gt;
&lt;td&gt;Revert completed, S3 APs still unavailable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Impact and Recommendation
&lt;/h3&gt;

&lt;p&gt;This is now tracked as an AWS Support case. Key takeaways:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plan throughput capacity changes during maintenance windows. S3 AP workloads may be disrupted for an extended period.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unlike standard S3 buckets, FSx for ONTAP S3 AP availability can be affected by FSx file system operational changes such as throughput capacity updates.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Important context&lt;/strong&gt;: AWS documentation states that NFS/SMB access typically remains available during throughput capacity changes. The S3 AP disruption I observed appears to be specific to the S3 Access Point data plane — not the file system's NFS/SMB data LIFs. This distinction matters for environments that use both protocols.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For regulated environments&lt;/strong&gt; (FISC, healthcare, government): Throughput capacity changes must be included in change management procedures. If S3 AP-based workloads have SLA requirements, the change should be approved through the organization's change advisory board with documented rollback procedures.&lt;/p&gt;

&lt;p&gt;This finding has been added to the &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns/blob/main/docs/production-readiness.md" rel="noopener noreferrer"&gt;Production Readiness&lt;/a&gt; document as a Level 3+ operational consideration.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. DEV.to Series Cleanup
&lt;/h2&gt;

&lt;p&gt;Phase 14 also cleaned up the article series:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Update Notes&lt;/strong&gt; added to Phase 1, 9, 10, 12 articles linking to Phase 13&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permission-Aware RAG&lt;/strong&gt; articles moved to a separate series (was incorrectly mixed into FSx S3AP series)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Series now has 14 articles&lt;/strong&gt; in "FSx for ONTAP S3 Access Points" (down from 16 after RAG separation)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Blockers and Current Status
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Blocker&lt;/th&gt;
&lt;th&gt;Resolution&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;del&gt;256/512 MBps benchmark&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;S3 AP ServiceUnavailable&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;Resolved 2026-05-25&lt;/strong&gt; — Results below&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FC1 Recovery Metrics&lt;/td&gt;
&lt;td&gt;FlexCache × S3 AP integration&lt;/td&gt;
&lt;td&gt;Pending AWS feature availability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;del&gt;Hypothesis verification&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;Depends on benchmark&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;Partially confirmed&lt;/strong&gt; — see results&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  6. Benchmark Results: 128 / 256 / 512 MBps Concurrency Comparison
&lt;/h2&gt;

&lt;p&gt;S3 AP ServiceUnavailable was resolved on 2026-05-25. We immediately executed the planned benchmark across all three throughput tiers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Environment
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note on methodology divergence&lt;/strong&gt;: The benchmark methodology (Section 3) defines 1769 MB Lambda + 50 iterations as the standard. The Internet tests below used a macOS client + 10 iterations per concurrency level due to the initial exploratory nature of these measurements. The Lambda egress test (Section 8) follows the 1769 MB / 50 iteration standard. Treat Internet results as directional sizing guidance, not as statistically rigorous benchmarks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Region&lt;/td&gt;
&lt;td&gt;ap-northeast-1 (Tokyo)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FSx for ONTAP&lt;/td&gt;
&lt;td&gt;Single-AZ, First-generation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 AP&lt;/td&gt;
&lt;td&gt;NetworkOrigin=Internet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Client&lt;/td&gt;
&lt;td&gt;macOS, boto3, Python 3.9 (public Internet)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Object sizes&lt;/td&gt;
&lt;td&gt;1 KB, 100 KB, 1 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Concurrency&lt;/td&gt;
&lt;td&gt;1, 5, 10, 20, 50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Iterations&lt;/td&gt;
&lt;td&gt;10 per concurrency level (exploratory)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Key Results: 1 MB GetObject P99
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concurrency&lt;/th&gt;
&lt;th&gt;128 MBps&lt;/th&gt;
&lt;th&gt;256 MBps&lt;/th&gt;
&lt;th&gt;512 MBps&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;76 ms&lt;/td&gt;
&lt;td&gt;93 ms&lt;/td&gt;
&lt;td&gt;96 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;160 ms&lt;/td&gt;
&lt;td&gt;175 ms&lt;/td&gt;
&lt;td&gt;308 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;239 ms&lt;/td&gt;
&lt;td&gt;236 ms&lt;/td&gt;
&lt;td&gt;229 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;981 ms&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;481 ms&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;738 ms&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;850 ms&lt;/td&gt;
&lt;td&gt;4,495 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Analysis
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;P50 (median) is largely independent of throughput capacity&lt;/strong&gt; — Internet baseline latency (connection + TLS) dominates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;P99 (tail latency) shows the difference&lt;/strong&gt; — 128→256 MBps improved P99 by 51% at concurrency=20&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;512 MBps shows no improvement over 256 MBps via Internet&lt;/strong&gt; — client-side bandwidth (~100 Mbps) becomes the bottleneck&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hypothesis partially confirmed&lt;/strong&gt;: Practical concurrency point does shift with throughput capacity, but the relationship is non-linear and bounded by client bandwidth in Internet-origin tests&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Sizing Guidance
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workload&lt;/th&gt;
&lt;th&gt;128 MBps&lt;/th&gt;
&lt;th&gt;256 MBps&lt;/th&gt;
&lt;th&gt;512 MBps&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Small files (&amp;lt; 10 KB)&lt;/td&gt;
&lt;td&gt;MaxConcurrency=20&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Medium files (100 KB)&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large files (1 MB+)&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;These are sizing references from a specific test environment, not service limits. A VPC-internal Lambda + VPC-origin S3 AP path is expected to reduce public Internet overhead, but remains untested and must be validated separately. Always validate with your own workload profile.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What This Means for Production
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;For PoC (128 MBps)&lt;/strong&gt;: Keep Step Functions Map state MaxConcurrency ≤ 5 for 1 MB+ files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For Production (256+ MBps)&lt;/strong&gt;: MaxConcurrency=10-20 is safe for most workloads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For VPC-internal Lambda (untested)&lt;/strong&gt;: Expected to further reduce latency by eliminating public Internet path, but requires VPC-origin S3 AP (not yet measured)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Throughput capacity changes&lt;/strong&gt;: Plan during maintenance windows (S3 AP disruption risk confirmed)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Small files (&amp;lt; 1 KB)&lt;/strong&gt;: Throughput capacity increase has no effect — bottleneck is connection overhead, not bandwidth. Save costs by staying at 128 MBps for metadata-heavy workloads&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7. Lambda Egress Path Benchmark: Reducing Connection Overhead
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Terminology clarification&lt;/strong&gt;: This test uses a &lt;strong&gt;VPC-external Lambda&lt;/strong&gt; (no VpcConfig) accessing an &lt;strong&gt;Internet-origin S3 AP&lt;/strong&gt;. The Lambda egress path goes through AWS-managed networking, which is faster than public Internet but is NOT a VPC-internal path. A true VPC-internal test would require a VPC-origin S3 AP + VPC-internal Lambda — that remains untested.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;What it measures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Public Internet client → Internet-origin S3 AP&lt;/td&gt;
&lt;td&gt;✅ Measured (Section 7)&lt;/td&gt;
&lt;td&gt;End-user/CI baseline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VPC-external Lambda → Internet-origin S3 AP&lt;/td&gt;
&lt;td&gt;✅ Measured (this section)&lt;/td&gt;
&lt;td&gt;AWS-managed Lambda egress, NOT VPC-private&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VPC-internal Lambda → VPC-origin S3 AP&lt;/td&gt;
&lt;td&gt;❌ Not yet measured&lt;/td&gt;
&lt;td&gt;True private path (requires new AP)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We deployed a benchmark Lambda (1769 MB, ARM64, &lt;strong&gt;no VpcConfig&lt;/strong&gt;) to measure GetObject latency via AWS-managed Lambda egress.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lambda Egress vs Internet: 1 MB GetObject P50
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concurrency&lt;/th&gt;
&lt;th&gt;Internet P50&lt;/th&gt;
&lt;th&gt;Lambda P50&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;68 ms&lt;/td&gt;
&lt;td&gt;62 ms&lt;/td&gt;
&lt;td&gt;9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;117 ms&lt;/td&gt;
&lt;td&gt;61 ms&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;48%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;175 ms&lt;/td&gt;
&lt;td&gt;73 ms&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;58%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;256 ms&lt;/td&gt;
&lt;td&gt;122 ms&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;52%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;128 ms&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Key Findings
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;P50 dramatically improved at concurrency &amp;gt; 1&lt;/strong&gt;: Lambda egress eliminates public Internet TCP connection overhead&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;P99 remains high (~1s)&lt;/strong&gt;: Even from Lambda, concurrency=20 shows P99 of 1,318 ms — this is the S3 AP data plane's internal queuing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;concurrency=50 P50 is only 128 ms&lt;/strong&gt;: Lambda threads are efficient against S3 AP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The bottleneck is the FSx for ONTAP S3 AP data plane&lt;/strong&gt;, not Lambda network bandwidth&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Production Sizing (Lambda)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workload&lt;/th&gt;
&lt;th&gt;Recommended MaxConcurrency&lt;/th&gt;
&lt;th&gt;Expected P50&lt;/th&gt;
&lt;th&gt;Expected P99&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Small files (1 KB)&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;~63 ms&lt;/td&gt;
&lt;td&gt;~994 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Medium files (100 KB)&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;~79 ms&lt;/td&gt;
&lt;td&gt;~1,044 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large files (1 MB)&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;~73 ms&lt;/td&gt;
&lt;td&gt;~928 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Set Lambda timeout to 30s+ and use Step Functions Retry to handle P99 spikes. These results are from VPC-external Lambda (AWS-managed egress), not true VPC-internal path.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  8. SQS Replay Storm Simulation: Zero Message Loss Under Load
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Scope clarification&lt;/strong&gt;: This test validates the &lt;strong&gt;downstream SQS ingestion and Lambda consumer drain path&lt;/strong&gt; under replay-like burst conditions. It does NOT validate ONTAP Persistent Store buffering or FPolicy TCP-level server reconnection replay. Those require a live FPolicy server environment (future work).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We simulated FPolicy server reconnection by injecting 1,000 and 10,000 events directly into SQS, mimicking the burst that occurs when a Persistent Store replays buffered events after server reconnection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Results
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Events&lt;/th&gt;
&lt;th&gt;Loss Rate&lt;/th&gt;
&lt;th&gt;Throughput&lt;/th&gt;
&lt;th&gt;Batch P99&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;5 min downtime&lt;/td&gt;
&lt;td&gt;1,000&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;188 eps&lt;/td&gt;
&lt;td&gt;177 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;30 min downtime&lt;/td&gt;
&lt;td&gt;10,000&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;464 eps&lt;/td&gt;
&lt;td&gt;79 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Consumer drain&lt;/td&gt;
&lt;td&gt;1,000&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;341 msgs/sec&lt;/td&gt;
&lt;td&gt;85 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  SLO Validation
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;SLO Metric&lt;/th&gt;
&lt;th&gt;Threshold&lt;/th&gt;
&lt;th&gt;Observed&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Event loss rate&lt;/td&gt;
&lt;td&gt;&amp;lt; 0.1%&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Injection throughput&lt;/td&gt;
&lt;td&gt;&amp;gt; 100 eps&lt;/td&gt;
&lt;td&gt;464 eps&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Consumer drain rate&lt;/td&gt;
&lt;td&gt;&amp;gt; injection rate&lt;/td&gt;
&lt;td&gt;341 &amp;gt; 188&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Batch latency P99&lt;/td&gt;
&lt;td&gt;&amp;lt; 200 ms&lt;/td&gt;
&lt;td&gt;79 ms&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DLQ messages&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Implications
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;30-min downtime&lt;/strong&gt; accumulates ~835K events at 464 eps. With Lambda auto-scaling (10 consumers), drain completes in &amp;lt; 5 minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistent Store sizing estimate&lt;/strong&gt;: Based on simulated event payload size, 10K events ≈ 5 MB. Real ONTAP Persistent Store sizing must be validated with live FPolicy replay.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No backpressure issues&lt;/strong&gt;: SQS Standard queue handles burst without message loss.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  9. Operational Runbook: S3 AP Disruption Response
&lt;/h2&gt;

&lt;p&gt;When S3 AP becomes unavailable (e.g., during throughput capacity changes):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check S3 AP health&lt;/strong&gt;: &lt;code&gt;ListObjectsV2&lt;/code&gt; / &lt;code&gt;GetObject&lt;/code&gt; against S3 AP alias&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check NFS/SMB separately&lt;/strong&gt;: mount + read test (may still be functional)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check FSx file system status&lt;/strong&gt;: &lt;code&gt;describe-file-systems&lt;/code&gt; → Lifecycle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check CloudWatch alarms&lt;/strong&gt;: Lambda errors, Step Functions failures&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pause ingestion&lt;/strong&gt;: Disable EventBridge Schedules for affected UC pipelines&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wait and retry&lt;/strong&gt;: S3 AP recovery may take 15-60 min after throughput changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escalate&lt;/strong&gt;: If unavailable &amp;gt; 60 min, contact AWS Support with file system ID&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;See &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns/blob/main/docs/incident-response-playbook.md" rel="noopener noreferrer"&gt;Incident Response Playbook&lt;/a&gt; for full procedures.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What's Next (Phase 15 candidates)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: Phase 15 expanded the pattern library from 17 to 28 industry-specific use cases. Items 1-2 below remain pending AWS feature availability. Items 3-4 are carried forward in Phase 15's What's Next.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;FlexCache × S3 AP integration&lt;/strong&gt; — pending AWS feature availability (not yet supported)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FC1 Recovery Metrics&lt;/strong&gt; — route decision latency, cache health detection, failover timing (depends on #1)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replay Storm with real FPolicy server&lt;/strong&gt; — TCP-level replay characteristics (requires ECS re-deploy)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VPC-internal Lambda with VPC Origin S3 AP&lt;/strong&gt; — true VPC-internal path (requires new AP with NetworkOrigin=VPC)&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Multi-Account OAM validation completed 2026-05-25 — cross-account CloudWatch Metrics, Logs, and X-Ray Traces confirmed working.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Field feedback tracked&lt;/strong&gt;: S3 AP disruption during throughput change, presigned URL documentation gap, VPC-origin benchmark gap, and FlexCache × S3 AP feature dependency. Details in &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns/blob/main/docs/ontap-integration-notes.md#field-feedback-log" rel="noopener noreferrer"&gt;&lt;code&gt;docs/ontap-integration-notes.md&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Files changed&lt;/strong&gt;: 200+ (documentation, translations, shared modules, templates)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New documents&lt;/strong&gt;: Partner/SI one-pager (JP/EN/KO/ZH-CN), cost calculator, customization guide, incident response playbook, demo mode guide, comparison alternatives, PoC Go/No-Go template&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New shared modules&lt;/strong&gt;: &lt;code&gt;data_classification.py&lt;/code&gt;, &lt;code&gt;human_review.py&lt;/code&gt;, &lt;code&gt;schemas/events.py&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Benchmark runs&lt;/strong&gt;: 7 (128/256/512 MBps Internet × 2 file sizes + Lambda egress + SQS replay storm simulation)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Templates fixed&lt;/strong&gt;: 5 (cfn-lint errors: RecursiveDeleteOption, SNSPublishMessagePolicy, Handler path)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Translations added&lt;/strong&gt;: 20 files (FC1-FC6 ko/zh-CN + FC1/FC3 full 8-lang)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;samconfig.toml.example&lt;/strong&gt;: 24 patterns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output JSON samples&lt;/strong&gt;: 24 patterns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DEV.to articles updated&lt;/strong&gt;: 6 (4 Update Notes + 2 Series changes)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Support cases&lt;/strong&gt;: 1 resolved (S3 AP ServiceUnavailable — throughput change related)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operational discoveries&lt;/strong&gt;: 1 (throughput change → S3 AP disruption, now resolved)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost savings&lt;/strong&gt;: ~$346/month (v4-test-demo + FPolicy server + VPC Endpoints + EC2 停止)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQS Replay Storm Simulation&lt;/strong&gt;: 10,000 events, 0% loss in downstream SQS/consumer path&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Who Should Care About Phase 14?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Partners and SIs&lt;/strong&gt; get a one-pager for first conversations and recommended questions for each FC pattern&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operations teams&lt;/strong&gt; learn that throughput capacity changes can disrupt S3 AP access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Architects&lt;/strong&gt; get standardized benchmark methodology with hypothesis-driven testing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developers&lt;/strong&gt; get Presigned URL clarification — works but don't depend on it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standard S3 bucket users&lt;/strong&gt; learn where FSx for ONTAP S3 AP differs from S3 bucket semantics, especially presigned URLs, availability, and operational dependencies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serverless-first teams&lt;/strong&gt; learn where the serverless processing plane ends and FSx for ONTAP operational considerations begin&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What You Can Do Today
&lt;/h2&gt;

&lt;p&gt;Phase 14 delivers immediately usable assets:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use the &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns/blob/main/docs/partner-si-one-pager.en.md" rel="noopener noreferrer"&gt;Partner/SI one-pager&lt;/a&gt;&lt;/strong&gt; for your next customer conversation about FSx for ONTAP + serverless&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check the &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns/blob/main/docs/s3ap-compatibility-notes.md" rel="noopener noreferrer"&gt;S3AP Compatibility Notes&lt;/a&gt;&lt;/strong&gt; for the latest Presigned URL and troubleshooting guidance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan throughput changes carefully&lt;/strong&gt; — add S3 AP health checks to your maintenance runbook&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use the Sizing Guidance tables&lt;/strong&gt; (Sections 7-8) to set MaxConcurrency for your workload&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review the &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns/blob/main/docs/s3-bucket-user-guide.md" rel="noopener noreferrer"&gt;S3 Bucket User Guide&lt;/a&gt;&lt;/strong&gt; before porting existing S3 applications to FSx for ONTAP S3 AP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review the &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns/blob/main/docs/ontap-integration-notes.md" rel="noopener noreferrer"&gt;ONTAP Integration Notes&lt;/a&gt;&lt;/strong&gt; before attaching S3 AP workflows to production SVMs and volumes&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Repository&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/FSx-for-ONTAP-S3AccessPoints-Serverless-Patterns&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full series&lt;/strong&gt;: &lt;a href="https://dev.to/yoshikifujiwara/series/39652"&gt;FSx for ONTAP S3 Access Points on DEV.to&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>amazonfsxfornetappontap</category>
      <category>s3accesspoints</category>
    </item>
    <item>
      <title>9 Services, One Architecture: What We Learned Shipping FSx for ONTAP Logs to Every Major Observability Platform</title>
      <dc:creator>Yoshiki Fujiwara(藤原 善基)@AWS Community Builder</dc:creator>
      <pubDate>Sun, 31 May 2026 01:42:23 +0000</pubDate>
      <link>https://dev.to/aws-builders/9-services-one-architecture-what-we-learned-shipping-fsx-for-ontap-logs-to-every-major-19ig</link>
      <guid>https://dev.to/aws-builders/9-services-one-architecture-what-we-learned-shipping-fsx-for-ontap-logs-to-every-major-19ig</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;We built and E2E-verified serverless integrations shipping FSx for ONTAP audit logs to &lt;strong&gt;9 observability platforms&lt;/strong&gt; — all from the same architecture:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For decision makers&lt;/strong&gt;: 90% cost reduction vs EC2-based collectors ($66/month → $5-8/month), 9 vendor choices instead of 1, 30-minute deploy instead of hours, zero operational burden. Four vendors offer permanent free tiers covering most FSx for ONTAP deployments (New Relic 100 GB, Grafana Cloud 50 GB, Honeycomb 20M events, Sumo Logic 500 MB/day).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    ┌─────────────────────────────────────────────┐
                    │         One Architecture, 9 Backends        │
                    ├─────────────────────────────────────────────┤
                    │                                             │
                    │  FSx for ONTAP ──→ S3 Access Point          │
                    │       │                                     │
                    │       ▼                                     │
                    │  EventBridge Scheduler (5 min)              │
                    │       │                                     │
                    │       ▼                                     │
                    │  Lambda (vendor-specific handler)           │
                    │       │                                     │
                    │       ├──→ Datadog (Logs API v2)            │
                    │       ├──→ New Relic (Log API v1)           │
                    │       ├──→ Splunk (HEC)                     │
                    │       ├──→ Grafana Cloud (OTLP Gateway)     │
                    │       ├──→ Elastic (Bulk API)               │
                    │       ├──→ Dynatrace (Log Ingest v2)        │
                    │       ├──→ Sumo Logic (HTTP Source)         │
                    │       ├──→ Honeycomb (Events Batch API)     │
                    │       └──→ OTel Collector (OTLP/HTTP)       │
                    │                                             │
                    └─────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;12 articles, 9 vendors, 3 event sources (audit logs, EMS webhooks, FPolicy), all CloudFormation-templated, all tested with real FSx for ONTAP data. This post distills what we learned.&lt;/p&gt;

&lt;p&gt;This is Part 13 — the series finale — of &lt;a href="https://dev.to/aws-builders/why-your-fsx-for-ontap-audit-logs-deserve-better-than-ec2-kod"&gt;Serverless Observability for FSx for ONTAP&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture That Survived 9 Integrations
&lt;/h2&gt;

&lt;p&gt;After implementing 9 vendor integrations, the core pattern remained unchanged:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# 1. Get cached credentials (Secrets Manager + TTL, default 5 min)
&lt;/span&gt;    &lt;span class="n"&gt;creds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# 2. List new files since checkpoint (S3 AP + SSM)
&lt;/span&gt;    &lt;span class="n"&gt;new_keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list_new_keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s3_ap_arn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;checkpoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 3. Read, parse, format, ship per file (vendor-specific)
&lt;/span&gt;    &lt;span class="c1"&gt;#    (Simplified — actual implementation batches events across files
&lt;/span&gt;    &lt;span class="c1"&gt;#     and respects vendor-specific batch size limits)
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;new_keys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;logs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_and_parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;format_for_vendor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Only this changes per vendor
&lt;/span&gt;
    &lt;span class="c1"&gt;# 4. Ship with retry (vendor API)
&lt;/span&gt;        &lt;span class="nf"&gt;ship_to_vendor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 5. Advance checkpoint (only after confirmed delivery)
&lt;/span&gt;        &lt;span class="nf"&gt;update_checkpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What changes per vendor: &lt;strong&gt;only the formatting and HTTP call&lt;/strong&gt; (~50-100 lines). Everything else — S3 AP access, checkpoint management, DLQ handling, credential caching, retry logic — is shared.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cross-Vendor Comparison: The Numbers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  API Characteristics
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vendor&lt;/th&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Auth Model&lt;/th&gt;
&lt;th&gt;Max Batch&lt;/th&gt;
&lt;th&gt;Success Code&lt;/th&gt;
&lt;th&gt;Firehose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Datadog&lt;/td&gt;
&lt;td&gt;Logs API v2&lt;/td&gt;
&lt;td&gt;Header (&lt;code&gt;DD-API-KEY&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;5 MB / 1000 items&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New Relic&lt;/td&gt;
&lt;td&gt;Log API v1&lt;/td&gt;
&lt;td&gt;Header (&lt;code&gt;Api-Key&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;1 MB&lt;/td&gt;
&lt;td&gt;202&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Splunk&lt;/td&gt;
&lt;td&gt;HEC&lt;/td&gt;
&lt;td&gt;Header (&lt;code&gt;Splunk &amp;lt;token&amp;gt;&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;No hard limit&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;Yes (built-in)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grafana&lt;/td&gt;
&lt;td&gt;OTLP Gateway&lt;/td&gt;
&lt;td&gt;Basic Auth (base64)&lt;/td&gt;
&lt;td&gt;~4 MB&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Elastic&lt;/td&gt;
&lt;td&gt;Bulk API&lt;/td&gt;
&lt;td&gt;Header (&lt;code&gt;ApiKey &amp;lt;b64&amp;gt;&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;~10 MB&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dynatrace&lt;/td&gt;
&lt;td&gt;Log Ingest v2&lt;/td&gt;
&lt;td&gt;Header (&lt;code&gt;Api-Token&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;1 MB&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;204&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Via ActiveGate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sumo Logic&lt;/td&gt;
&lt;td&gt;HTTP Source&lt;/td&gt;
&lt;td&gt;URL-embedded token&lt;/td&gt;
&lt;td&gt;1 MB&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Honeycomb&lt;/td&gt;
&lt;td&gt;Events Batch&lt;/td&gt;
&lt;td&gt;Header (&lt;code&gt;x-honeycomb-team&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;5 MB (impl: 100/batch)&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OTel Collector&lt;/td&gt;
&lt;td&gt;OTLP/HTTP&lt;/td&gt;
&lt;td&gt;Configurable&lt;/td&gt;
&lt;td&gt;Configurable&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Cost at 10 GB/month
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vendor&lt;/th&gt;
&lt;th&gt;Vendor Cost&lt;/th&gt;
&lt;th&gt;AWS Infra&lt;/th&gt;
&lt;th&gt;Total&lt;/th&gt;
&lt;th&gt;Free Tier&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sumo Logic&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~$5&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~$5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;500 MB/day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Honeycomb&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~$5&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~$5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;20M events/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New Relic&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~$5&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~$5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;100 GB/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grafana Cloud&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~$5&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~$5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;50 GB logs/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Datadog&lt;/td&gt;
&lt;td&gt;~$15&lt;/td&gt;
&lt;td&gt;~$5&lt;/td&gt;
&lt;td&gt;~$20&lt;/td&gt;
&lt;td&gt;Logs: 14-day trial only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dynatrace&lt;/td&gt;
&lt;td&gt;~$25&lt;/td&gt;
&lt;td&gt;~$5&lt;/td&gt;
&lt;td&gt;~$30&lt;/td&gt;
&lt;td&gt;14-day trial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Elastic Cloud&lt;/td&gt;
&lt;td&gt;~$95&lt;/td&gt;
&lt;td&gt;~$5&lt;/td&gt;
&lt;td&gt;~$100&lt;/td&gt;
&lt;td&gt;14-day trial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Splunk Cloud&lt;/td&gt;
&lt;td&gt;~$150+&lt;/td&gt;
&lt;td&gt;~$5&lt;/td&gt;
&lt;td&gt;~$155+&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;AWS infrastructure cost is consistent across all vendors (~$5/month for Lambda + EventBridge + Secrets Manager). The vendor platform cost is the differentiator.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Data Residency
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vendor&lt;/th&gt;
&lt;th&gt;Tokyo (JP)&lt;/th&gt;
&lt;th&gt;US&lt;/th&gt;
&lt;th&gt;EU&lt;/th&gt;
&lt;th&gt;Self-Hosted&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sumo Logic&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Elastic&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dynatrace&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; (region-specific)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; (Managed)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Datadog&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New Relic&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;No&lt;/strong&gt; (July 2026 planned)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grafana Cloud&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Dedicated only&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No (Alloy self-hosted)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Splunk&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Honeycomb&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Governance note&lt;/strong&gt;: This table provides technical awareness for vendor selection. Grafana Cloud offers Tokyo region on Dedicated tier (not Free/Pro). Data residency alone does not constitute regulatory compliance. Evaluate your specific requirements (APPI, GDPR, FISC, ISMAP) with your compliance team. See the &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/retention-policy-matrix.md" rel="noopener noreferrer"&gt;Retention Policy Matrix&lt;/a&gt; for regulation-to-vendor mapping.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Unique Strengths
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vendor&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Datadog&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full-stack APM correlation, broadest feature set&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;New Relic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Generous free tier (100 GB), NRQL power&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Splunk&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Existing Splunk shops, SPL expertise, Firehose native&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Grafana Cloud&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;OTLP-native, LogQL, open-source ecosystem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Elastic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Data sovereignty (self-hosted), ECS/SIEM, Kibana&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dynatrace&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Davis AI root cause analysis, APM correlation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sumo Logic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;JP region data residency, generous free tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Honeycomb&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High-cardinality analysis (BubbleUp, Heatmaps)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OTel Collector&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multi-backend, vendor portability, redaction&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note on Grafana ecosystem&lt;/strong&gt;: Grafana Alloy (formerly Grafana Agent) provides a Grafana-native alternative to the OpenTelemetry Collector with the same OTLP compatibility. Grafana Cloud's OTLP Gateway is available on all tiers including Free (US/EU regions only). For Tokyo data residency, Grafana Cloud Dedicated is required.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  7 Patterns That Survived All 9 Integrations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Polling &amp;gt; Event-Driven (for FSx for ONTAP S3 AP)
&lt;/h3&gt;

&lt;p&gt;FSx for ONTAP S3 Access Points don't support S3 Event Notifications. We evaluated CloudTrail data events as an alternative — however, CloudTrail data events for FSx for ONTAP S3 AP access are not consistently available across all configurations. The 5-minute EventBridge Scheduler poll is simpler, cheaper, and sufficient for audit log use cases where near-real-time (not real-time) delivery is acceptable.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Checkpoint-After-Delivery
&lt;/h3&gt;

&lt;p&gt;Never advance the checkpoint before confirming vendor delivery. This single rule prevents data loss across all failure modes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# CORRECT: checkpoint after confirmed delivery
&lt;/span&gt;&lt;span class="nf"&gt;ship_to_vendor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Raises on failure
&lt;/span&gt;&lt;span class="nf"&gt;update_checkpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# Only reached on success
&lt;/span&gt;
&lt;span class="c1"&gt;# WRONG: checkpoint before delivery
&lt;/span&gt;&lt;span class="nf"&gt;update_checkpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# What if ship_to_vendor fails next?
&lt;/span&gt;&lt;span class="nf"&gt;ship_to_vendor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Data loss if this fails
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Credential Caching with Reload-on-401
&lt;/h3&gt;

&lt;p&gt;Every vendor integration uses the same &lt;code&gt;SecretBackedAuth&lt;/code&gt; pattern: cache credentials at cold start, reload on TTL expiry or 401/403. This handles credential rotation without Lambda redeployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Reserved Concurrency = 1
&lt;/h3&gt;

&lt;p&gt;The audit poller must not run concurrently (checkpoint race condition). &lt;code&gt;ReservedConcurrentExecutions: 1&lt;/code&gt; is the simplest guard. For higher throughput, move to DynamoDB-based per-object locking.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. DLQ for Every Async Path
&lt;/h3&gt;

&lt;p&gt;Every template includes a KMS-encrypted DLQ. In 9 integrations, the DLQ caught: vendor outages, credential expiry, malformed files, and Lambda timeouts. Without it, these failures would be silent data loss.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Vendor-Specific Batch Limits Matter
&lt;/h3&gt;

&lt;p&gt;The biggest implementation difference across vendors is batch size handling:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vendor&lt;/th&gt;
&lt;th&gt;Limit&lt;/th&gt;
&lt;th&gt;Lambda Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Honeycomb&lt;/td&gt;
&lt;td&gt;100 events&lt;/td&gt;
&lt;td&gt;Split into chunks of 100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dynatrace / Sumo Logic&lt;/td&gt;
&lt;td&gt;1 MB&lt;/td&gt;
&lt;td&gt;Measure payload size, split at boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Datadog&lt;/td&gt;
&lt;td&gt;5 MB / 1000 items&lt;/td&gt;
&lt;td&gt;Dual limit check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Elastic&lt;/td&gt;
&lt;td&gt;~10 MB&lt;/td&gt;
&lt;td&gt;Rarely hit with audit logs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  7. OTLP as the Universal Format
&lt;/h3&gt;

&lt;p&gt;If you're unsure which vendor you'll use long-term, start with OTLP. The OTel Collector integration (Part 5) proved that a single Lambda producing OTLP can feed Datadog, Grafana, and Honeycomb simultaneously — with zero code changes when adding or removing backends.&lt;/p&gt;

&lt;p&gt;Beyond multi-backend delivery, the OTel Collector provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enrichment&lt;/strong&gt;: Resource detection, Kubernetes attributes, custom metadata injection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sampling&lt;/strong&gt;: Tail-based sampling for high-volume environments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redaction&lt;/strong&gt;: PII field removal/masking before data leaves your account (see &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/integrations/otel-collector/docs/en/pii-redaction-cookbook.md" rel="noopener noreferrer"&gt;PII Redaction Cookbook&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Format conversion&lt;/strong&gt;: OTLP ↔ vendor-native format translation&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Verified version&lt;/strong&gt;: All OTel Collector configurations in this series were tested with &lt;strong&gt;OpenTelemetry Collector Contrib v0.152.0&lt;/strong&gt;. OTel Collector has frequent releases with potential breaking changes — pin your version in production and test before upgrading.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What We'd Do Differently
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Start with OTel Collector for Multi-Vendor Evaluation
&lt;/h3&gt;

&lt;p&gt;If evaluating multiple vendors, deploy the OTel Collector path first. It lets you send the same data to 2-3 vendors simultaneously for comparison, without deploying separate Lambda stacks per vendor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Define SLOs Before Building
&lt;/h3&gt;

&lt;p&gt;We defined Pipeline SLOs after building all 9 integrations. In hindsight, defining "&amp;lt; 10 min delivery latency" and "&amp;lt; 0.01% data loss" upfront would have guided design decisions earlier (e.g., checkpoint granularity, retry policy).&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Classification First
&lt;/h3&gt;

&lt;p&gt;Audit logs contain PII (usernames, file paths). We documented this in the Data Classification Guide after implementation. For regulated environments, classify fields before choosing a vendor — it may eliminate options that don't support your data residency requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production Readiness Framework
&lt;/h2&gt;

&lt;p&gt;After 9 integrations, we formalized a 4-level production readiness model:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;What&lt;/th&gt;
&lt;th&gt;Go/No-Go to Next&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Level 1&lt;/strong&gt;: Quickstart&lt;/td&gt;
&lt;td&gt;Audit poller + DLQ&lt;/td&gt;
&lt;td&gt;Logs arrive, checkpoint advances, DLQ empty 24h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Level 2&lt;/strong&gt;: Operational PoC&lt;/td&gt;
&lt;td&gt;+ Dashboard + alerts&lt;/td&gt;
&lt;td&gt;SLOs met 7 days, security review done&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Level 3&lt;/strong&gt;: Production&lt;/td&gt;
&lt;td&gt;+ DynamoDB ledger + poison-pill&lt;/td&gt;
&lt;td&gt;SLOs met 30 days, compliance pack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Level 4&lt;/strong&gt;: Enterprise&lt;/td&gt;
&lt;td&gt;+ OTel Collector + redaction&lt;/td&gt;
&lt;td&gt;Multi-backend, PII redaction, DR tested&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Most PoCs should target Level 2. Production deployments need Level 3. Enterprise pipelines with compliance requirements need Level 4.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommended transition timeline&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Level 1 → Level 2: ~1 week (add dashboards, define SLOs, validate 7-day stability)&lt;/li&gt;
&lt;li&gt;Level 2 → Level 3: ~2-4 weeks (deploy DynamoDB ledger, implement poison-pill handling, complete security review)&lt;/li&gt;
&lt;li&gt;Level 3 → Level 4: ~1-2 months (deploy OTel Collector, implement PII redaction, test DR failover, complete compliance evidence pack)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full criteria: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/pipeline-slo.md" rel="noopener noreferrer"&gt;Pipeline SLO Definitions&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Vendor Selection Decision Tree
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start
  |
  +-- Need JP data residency?
  |   +-- Yes -&amp;gt; Sumo Logic (JP) or Elastic (self-hosted in Tokyo VPC)
  |   +-- No  |
  |           v
  +-- Need self-hosted (air-gapped)?
  |   +-- Yes -&amp;gt; Elastic or Splunk
  |   +-- No  |
  |           v
  +-- Already have an observability platform?
  |   +-- Yes -&amp;gt; Use that vendor (all 9 are supported)
  |   +-- No  |
  |           v
  +-- Budget constraint (free tier needed)?
  |   +-- Yes -&amp;gt; Sumo Logic (500 MB/day) or Honeycomb (20M events) or New Relic (100 GB)
  |   +-- No  |
  |           v
  +-- Need AI-powered root cause analysis?
  |   +-- Yes -&amp;gt; Dynatrace (Davis AI)
  |   +-- No  |
  |           v
  +-- Need high-cardinality analysis?
  |   +-- Yes -&amp;gt; Honeycomb (BubbleUp)
  |   +-- No  |
  |           v
  +-- Need multi-backend / vendor portability?
  |   +-- Yes -&amp;gt; OTel Collector
  |   +-- No  |
  |           v
  +-- Default -&amp;gt; Datadog (broadest) or Grafana (OTLP-native, open ecosystem)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The FSx for ONTAP S3 AP Constraint That Shaped Everything
&lt;/h2&gt;

&lt;p&gt;The single most impactful technical constraint: &lt;strong&gt;FSx for ONTAP S3 Access Points do not support S3 Event Notifications&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This one fact drove:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EventBridge Scheduler polling pattern (not event-driven)&lt;/li&gt;
&lt;li&gt;SSM Parameter Store checkpointing (track what's been processed)&lt;/li&gt;
&lt;li&gt;Reserved concurrency = 1 (prevent checkpoint races)&lt;/li&gt;
&lt;li&gt;Safety threshold (stop before Lambda timeout)&lt;/li&gt;
&lt;li&gt;MAX_KEYS_PER_RUN (bound processing per invocation)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If FSx for ONTAP S3 APs add event notification support in the future, the architecture could simplify significantly. As of May 2026, this feature is not supported, and the polling pattern is battle-tested across 9 vendors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost Reality: EC2 vs Serverless
&lt;/h2&gt;

&lt;p&gt;The original motivation: replace the &lt;a href="https://aws.amazon.com/jp/blogs/news/auditing-user-and-administrative-actions-on-amazon-fsx-for-netapp-ontap-using-splunk/" rel="noopener noreferrer"&gt;EC2-based Splunk pattern&lt;/a&gt; (2x EC2 instances) with serverless.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;EC2 Pattern&lt;/th&gt;
&lt;th&gt;Serverless Pattern&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Monthly AWS cost&lt;/td&gt;
&lt;td&gt;~$66&lt;/td&gt;
&lt;td&gt;~$5-8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OS patching&lt;/td&gt;
&lt;td&gt;Required&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaling&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vendor support&lt;/td&gt;
&lt;td&gt;Splunk only&lt;/td&gt;
&lt;td&gt;9 vendors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy time&lt;/td&gt;
&lt;td&gt;Hours&lt;/td&gt;
&lt;td&gt;30 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recovery from failure&lt;/td&gt;
&lt;td&gt;Manual restart&lt;/td&gt;
&lt;td&gt;Automatic (DLQ + retry)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;90% cost reduction&lt;/strong&gt; with zero operational burden. The serverless pattern wins on every dimension except one: real-time latency (EC2 syslog can be sub-second; our poller is 5-minute intervals). For audit logs, 5 minutes is acceptable. For real-time needs, use the FPolicy path (&amp;lt; 30 seconds).&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;This series covered the foundation. The project continues with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Phase 3 (delivered)&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/multi-account-deployment.md" rel="noopener noreferrer"&gt;Multi-account deployment&lt;/a&gt; (AWS Organizations + StackSets)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Phase 3 (delivered)&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/shared/python/object_ledger.py" rel="noopener noreferrer"&gt;DynamoDB object ledger&lt;/a&gt; for per-object processing state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Phase 3 (delivered)&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/shared/templates/sqs-buffering.yaml" rel="noopener noreferrer"&gt;SQS buffering pattern&lt;/a&gt; for backpressure handling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Phase 3 (delivered)&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/cross-region-replication.md" rel="noopener noreferrer"&gt;Cross-region DR&lt;/a&gt; with Active-Passive failover&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Phase 3 (delivered)&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/integrations/otel-collector/docs/en/pii-redaction-cookbook.md" rel="noopener noreferrer"&gt;OTel Collector PII redaction cookbook&lt;/a&gt; (7 recipes for APPI/GDPR)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Phase 4&lt;/strong&gt;: Terraform module equivalents&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Phase 4&lt;/strong&gt;: CDK construct library&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See the full &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/ROADMAP.md" rel="noopener noreferrer"&gt;ROADMAP&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/fsxn-observability-integrations&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pipeline SLO&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/pipeline-slo.md" rel="noopener noreferrer"&gt;docs/en/pipeline-slo.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Classification&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/data-classification.md" rel="noopener noreferrer"&gt;docs/en/data-classification.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S3 AP Throughput Benchmark&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/s3ap-throughput-benchmark.md" rel="noopener noreferrer"&gt;docs/en/s3ap-throughput-benchmark.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vendor Comparison&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/vendor-comparison.md" rel="noopener noreferrer"&gt;docs/en/vendor-comparison.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Partner FAQ&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/partner-faq.md" rel="noopener noreferrer"&gt;docs/en/partner-faq.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workshop Guide&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/workshop-hands-on-half-day.md" rel="noopener noreferrer"&gt;docs/en/workshop-hands-on-half-day.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance Evidence Pack&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/compliance-evidence-pack.md" rel="noopener noreferrer"&gt;docs/en/compliance-evidence-pack.md&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Series Navigation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Part 1&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/why-your-fsx-for-ontap-audit-logs-deserve-better-than-ec2-kod"&gt;Why Your FSx for ONTAP Audit Logs Deserve Better Than EC2&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 2&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/shipping-fsx-for-ontap-logs-to-datadog-the-serverless-way-n9c"&gt;Shipping FSx for ONTAP Logs to Datadog — The Serverless Way&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 3&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/event-driven-ransomware-detection-with-ontap-arp-datadog-4cda"&gt;Event-Driven Ransomware Detection with ONTAP ARP + Datadog&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 4&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/fpolicy-file-activity-pipeline-ontap-to-datadog-via-ecs-fargate-2ing"&gt;FPolicy File Activity Pipeline — ONTAP to Datadog via ECS Fargate&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 5&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/escape-vendor-lock-in-multi-backend-log-delivery-with-otel-collector-for-fsx-for-ontap-2inb"&gt;Escape Vendor Lock-in: Multi-Backend Log Delivery with OTel Collector for FSx for ONTAP.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 6&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/direct-to-grafana-shipping-fsx-for-ontap-logs-to-grafana-cloud-loki-via-otlp-gateway-33hk"&gt;Direct-to-Grafana: Shipping FSx for ONTAP Logs to Grafana Cloud Loki via OTLP Gateway&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 7&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ship-fsx-for-ontap-audit-logs-to-new-relic-via-serverless-lambda-pipeline-3g87"&gt;Ship FSx for ONTAP Audit Logs to New Relic via Serverless Lambda Pipeline&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 8&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ec2-to-serverless-modernizing-fsx-for-ontap-splunk-integration-e8l"&gt;EC2 to Serverless: Modernizing FSx for ONTAP Splunk Integration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 9&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/data-sovereignty-fsx-for-ontap-logs-in-your-vpc-with-elastic-1mog"&gt;Data Sovereignty: FSx for ONTAP Logs in Your VPC with Elastic&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 10&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/high-cardinality-file-access-analysis-with-honeycomb-otel-1962"&gt;High-Cardinality File Access Analysis with Honeycomb + OTel&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 11&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ai-powered-root-cause-correlating-file-access-with-apm-via-dynatrace-4ffl"&gt;AI-Powered Root Cause: Correlating File Access with APM via Dynatrace&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 12&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/fsx-for-ontap-audit-logs-with-data-residency-in-your-region-46e6"&gt;FSx for ONTAP Audit Logs with Data Residency in your region with Sumo Logic&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 13&lt;/strong&gt;: 9 Vendors, One Architecture (this post)&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Thank you for following this series. If you've deployed any of these integrations, I'd love to hear about your experience — drop a comment or open a GitHub issue.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/fsxn-observability-integrations&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>observability</category>
      <category>amazonfsxfornetappontap</category>
      <category>serverless</category>
    </item>
    <item>
      <title>FSx for ONTAP Audit Logs with Data Residency in your region with Sumo Logic</title>
      <dc:creator>Yoshiki Fujiwara(藤原 善基)@AWS Community Builder</dc:creator>
      <pubDate>Sun, 31 May 2026 00:37:19 +0000</pubDate>
      <link>https://dev.to/aws-builders/fsx-for-ontap-audit-logs-with-data-residency-in-your-region-46e6</link>
      <guid>https://dev.to/aws-builders/fsx-for-ontap-audit-logs-with-data-residency-in-your-region-46e6</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;We built a serverless Lambda pipeline that ships FSx for ONTAP audit logs to Sumo Logic's &lt;strong&gt;JP (Tokyo) region&lt;/strong&gt; deployment. For Japanese enterprises with data residency requirements under APPI (Act on the Protection of Personal Information), this means audit logs never leave Japan.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FSx for ONTAP → S3 Access Point → EventBridge Scheduler → Lambda → Sumo Logic HTTP Source (JP)
                                                                         │
                                                                         ▼
                                                              ┌───────────────────┐
                                                              │ Sumo Logic JP     │
                                                              │ (Tokyo)           │
                                                              │                   │
                                                              │ • 500 MB/day FREE │
                                                              │ • Data stays in   │
                                                              │   Japan           │
                                                              │ • 7-day retention │
                                                              │   (free tier)     │
                                                              └───────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;500 MB/day free tier&lt;/strong&gt; (~15 GB/month) — covers most FSx for ONTAP deployments at zero vendor cost&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JP region deployment&lt;/strong&gt; — data residency in Tokyo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplest auth model&lt;/strong&gt; — URL-embedded token, no header management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;30-minute end-to-end&lt;/strong&gt; — HTTP Source URL is the only credential needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Verified on Sumo Logic JP region. Logs searchable via &lt;code&gt;_sourceCategory=aws/fsxn/audit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is Part 12 of the &lt;a href="https://dev.to/aws-builders/why-your-fsx-for-ontap-audit-logs-deserve-better-than-ec2-kod"&gt;Serverless Observability for FSx for ONTAP&lt;/a&gt; series.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Sumo Logic for Japanese Enterprises?
&lt;/h2&gt;

&lt;p&gt;For organizations operating under Japanese data protection regulations, the choice of observability platform often comes down to one question: &lt;strong&gt;where does the data physically reside?&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;Sumo Logic JP&lt;/th&gt;
&lt;th&gt;Other Options&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Data residency in Japan&lt;/td&gt;
&lt;td&gt;✅ Tokyo deployment&lt;/td&gt;
&lt;td&gt;Varies by vendor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;APPI compliance consideration&lt;/td&gt;
&lt;td&gt;✅ Data stays in JP&lt;/td&gt;
&lt;td&gt;May require cross-border assessment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Free tier for validation&lt;/td&gt;
&lt;td&gt;✅ 500 MB/day&lt;/td&gt;
&lt;td&gt;Most offer 14-day trials only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No agent installation&lt;/td&gt;
&lt;td&gt;✅ HTTP Source (agentless)&lt;/td&gt;
&lt;td&gt;Some require collectors&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sumo Logic's JP deployment (&lt;code&gt;service.jp.sumologic.com&lt;/code&gt;) processes and stores all data within Japan, making it a straightforward choice for organizations that need to demonstrate data residency compliance.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Compliance note&lt;/strong&gt;: This integration provides a technical path for data residency. Evaluate your specific regulatory requirements with your compliance team — data residency alone does not constitute full regulatory compliance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────┐
│ Event Sources                                           │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  EventBridge Scheduler                                  │
│  rate(5 minutes) ──→ Lambda                             │
│                       │ lists new files via             │
│                       │ S3 Access Point                 │
│                       │ (checkpoint in SSM)             │
│                       ▼                                 │
│           Sumo Logic HTTP Source                        │
│           (URL-embedded auth)                           │
│                       │                                 │
│  EMS Webhook          │                                 │
│  ──→ API GW ──→ Lambda ─────────────┤                   │
│     (ems_handler)                   │                   │
│                                     ▼                   │
│  FPolicy                       Sumo Logic               │
│  ──→ ECS Fargate ──→ SQS      (Log Search,              │
│  ──→ Bridge Lambda              Dashboards,             │
│  ──→ EventBridge                Alerts)                 │
│  ──→ Lambda (fpolicy_handler) ──────────────────────────┤
└─────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Simplest Auth Model
&lt;/h2&gt;

&lt;p&gt;Sumo Logic's HTTP Source embeds the authentication token directly in the URL. No separate auth headers, no API key management, no token rotation complexity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;https://collectors.jp.sumologic.com/receiver/v1/http/&amp;lt;TOKEN&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lambda just POSTs JSON to this URL. That's it. The metadata (source category, name, host) is sent via &lt;code&gt;X-Sumo-*&lt;/code&gt; headers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-Sumo-Category&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aws/fsxn/audit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-Sumo-Name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fsxn-ontap-audit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-Sumo-Host&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fsxn-ontap&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Security&lt;/strong&gt;: The HTTP Source URL contains the auth token. Store it in Secrets Manager, never log it, and never expose it in environment variables or source control.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Quick Start (30 Minutes)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create Sumo Logic Account (JP Region)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Sign up at &lt;a href="https://service.jp.sumologic.com/" rel="noopener noreferrer"&gt;service.jp.sumologic.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;APAC: Tokyo (JP)&lt;/strong&gt; as your deployment region&lt;/li&gt;
&lt;li&gt;Free tier: 500 MB/day, 7-day retention, full feature access for 30 days&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2. Create Hosted Collector + HTTP Source
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Manage Data&lt;/strong&gt; → &lt;strong&gt;Collection&lt;/strong&gt; → &lt;strong&gt;Add Collector&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Hosted Collector&lt;/strong&gt; (name: &lt;code&gt;fsxn-audit-collector&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Add &lt;strong&gt;HTTP Logs &amp;amp; Metrics Source&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;fsxn-ontap-audit&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Source Category: &lt;code&gt;aws/fsxn/audit&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Timestamp Parsing: Auto-detect&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Copy the generated HTTP Source URL&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  3. Store HTTP Source URL
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws secretsmanager create-secret &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"sumo-logic/fsxn-http-source"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--secret-string&lt;/span&gt; &lt;span class="s1"&gt;'{"url":"https://collectors.jp.sumologic.com/receiver/v1/http/&amp;lt;YOUR_TOKEN&amp;gt;"}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; ap-northeast-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Deploy CloudFormation Stack
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudformation deploy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--template-file&lt;/span&gt; integrations/sumo-logic/template.yaml &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--stack-name&lt;/span&gt; fsxn-sumo-logic-integration &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--parameter-overrides&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;S3AccessPointArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arn:aws:s3:ap-northeast-1:123456789012:accesspoint/fsxn-audit-ap &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;SumoLogicHttpSourceSecretArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:sumo-logic/fsxn-http-source-XXXXXX &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;S3BucketName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;my-fsxn-audit-bucket &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--capabilities&lt;/span&gt; CAPABILITY_NAMED_IAM &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; ap-northeast-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Verify in Sumo Logic
&lt;/h3&gt;

&lt;p&gt;Run this search query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_sourceCategory=aws/fsxn/audit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: First-time indexing on a new JP region account takes ~10 minutes. Subsequent ingestion is near-instant.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Query Examples
&lt;/h2&gt;

&lt;p&gt;Sumo Logic uses a pipe-based query language:&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic Investigation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- All failed access attempts with user and path&lt;/span&gt;
&lt;span class="n"&gt;_sourceCategory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fsxn&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;audit&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="nv"&gt;"Result"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;"UserName"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;"ObjectName"&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="k"&gt;Result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;"Failure"&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;UserName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ObjectName&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sort&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;_count&lt;/span&gt; &lt;span class="k"&gt;desc&lt;/span&gt;

&lt;span class="c1"&gt;-- Top operations by volume&lt;/span&gt;
&lt;span class="n"&gt;_sourceCategory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fsxn&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;audit&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="nv"&gt;"Operation"&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="k"&gt;Operation&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sort&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;_count&lt;/span&gt; &lt;span class="k"&gt;desc&lt;/span&gt;

&lt;span class="c1"&gt;-- Access pattern timeline (5-minute buckets)&lt;/span&gt;
&lt;span class="n"&gt;_sourceCategory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fsxn&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;audit&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="nv"&gt;"Operation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;"UserName"&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;timeslice&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;_timeslice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;Operation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Security Investigation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- After-hours access (outside 9am-6pm JST)&lt;/span&gt;
&lt;span class="n"&gt;_sourceCategory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fsxn&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;audit&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="nv"&gt;"UserName"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;"Operation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;"ObjectName"&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;_messagetime&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;today&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;_messagetime&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;today&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;UserName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;Operation&lt;/span&gt;

&lt;span class="c1"&gt;-- Bulk delete detection (potential data exfiltration)&lt;/span&gt;
&lt;span class="n"&gt;_sourceCategory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fsxn&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;audit&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="nv"&gt;"Operation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;"UserName"&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="k"&gt;Operation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;"Delete"&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;timeslice&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;_timeslice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UserName&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;_count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;

&lt;span class="c1"&gt;-- Sensitive path access&lt;/span&gt;
&lt;span class="n"&gt;_sourceCategory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fsxn&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;audit&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="nv"&gt;"ObjectName"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;"UserName"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;"Result"&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;ObjectName&lt;/span&gt; &lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="nv"&gt;"*confidential*"&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;ObjectName&lt;/span&gt; &lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="nv"&gt;"*restricted*"&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;UserName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;Result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Operational Monitoring
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Log volume trend (capacity planning)&lt;/span&gt;
&lt;span class="n"&gt;_sourceCategory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fsxn&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;audit&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;timeslice&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;_timeslice&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;outlier&lt;/span&gt; &lt;span class="n"&gt;_count&lt;/span&gt;

&lt;span class="c1"&gt;-- SVM activity comparison&lt;/span&gt;
&lt;span class="n"&gt;_sourceCategory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fsxn&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;audit&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="nv"&gt;"SVMName"&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;timeslice&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;_timeslice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SVMName&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sumo Logic Metadata Headers
&lt;/h2&gt;

&lt;p&gt;Lambda sends structured metadata with each request:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Header&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;X-Sumo-Category&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;aws/fsxn/audit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Primary search dimension&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;X-Sumo-Name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;fsxn-ontap-audit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Source identification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;X-Sumo-Host&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;fsxn-ontap&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Host-level grouping&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These headers enable efficient searching without parsing the log body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Search by metadata (fast, no JSON parsing)&lt;/span&gt;
&lt;span class="n"&gt;_sourceCategory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fsxn&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;audit&lt;/span&gt; &lt;span class="n"&gt;_sourceHost&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fsxn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ontap&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cost Analysis: The Free Tier Advantage
&lt;/h2&gt;

&lt;p&gt;Sumo Logic's free tier is the most generous for small-to-medium FSx for ONTAP deployments:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Monthly Log Volume&lt;/th&gt;
&lt;th&gt;Daily Average&lt;/th&gt;
&lt;th&gt;Sumo Logic Tier&lt;/th&gt;
&lt;th&gt;Monthly Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1 GB&lt;/td&gt;
&lt;td&gt;~33 MB/day&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Free&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5 GB&lt;/td&gt;
&lt;td&gt;~167 MB/day&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Free&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10 GB&lt;/td&gt;
&lt;td&gt;~333 MB/day&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Free&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15 GB&lt;/td&gt;
&lt;td&gt;~500 MB/day&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Free&lt;/strong&gt; (at limit)&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;30 GB&lt;/td&gt;
&lt;td&gt;~1 GB/day&lt;/td&gt;
&lt;td&gt;Professional&lt;/td&gt;
&lt;td&gt;~$108/month&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Monthly Cost (10 GB/month)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lambda (5-min polling)&lt;/td&gt;
&lt;td&gt;~$3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EventBridge Scheduler&lt;/td&gt;
&lt;td&gt;~$1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secrets Manager&lt;/td&gt;
&lt;td&gt;~$1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sumo Logic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;$0&lt;/strong&gt; (within free tier)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~$5&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;For most FSx for ONTAP deployments generating &amp;lt; 15 GB/month of audit logs, the total cost is just the AWS infrastructure (~$5/month). The observability platform itself is free.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Sumo Logic Deployment Regions
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Region&lt;/th&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;th&gt;Data Residency&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;JP (Tokyo)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;service.jp.sumologic.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Japan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;US1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;service.sumologic.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;US&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;US2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;service.us2.sumologic.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;US&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EU (Ireland)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;service.eu.sumologic.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;EU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AU (Sydney)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;service.au.sumologic.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Australia&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IN (Mumbai)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;service.in.sumologic.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;India&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CA (Montreal)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;service.ca.sumologic.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Canada&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Select the deployment matching your data residency requirements at account creation time. &lt;strong&gt;Region cannot be changed after account creation.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Gotchas &amp;amp; Lessons Learned
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Discovery&lt;/th&gt;
&lt;th&gt;Impact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;JP region new accounts have ~10 minute initial indexing lag&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;First search returns empty; wait and retry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Search queries use &lt;code&gt;_sourceCategory&lt;/code&gt; (underscore prefix)&lt;/td&gt;
&lt;td&gt;Common mistake: &lt;code&gt;sourceCategory&lt;/code&gt; without underscore returns nothing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;HTTP Source URL contains embedded auth token&lt;/td&gt;
&lt;td&gt;Rotate by creating a new HTTP Source, updating the Secrets Manager secret, then deleting the old Source&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Free tier has 7-day retention only&lt;/td&gt;
&lt;td&gt;Sufficient for real-time monitoring; archive to S3 for long-term&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;No built-in Firehose support&lt;/td&gt;
&lt;td&gt;Lambda direct delivery only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Max 1MB per request (newline-delimited JSON)&lt;/td&gt;
&lt;td&gt;Lambda batches accordingly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Region is permanent — cannot migrate data between deployments&lt;/td&gt;
&lt;td&gt;Choose JP at signup for data residency&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Free Tier vs Professional
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Free (500 MB/day)&lt;/th&gt;
&lt;th&gt;Professional&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Daily ingestion&lt;/td&gt;
&lt;td&gt;500 MB&lt;/td&gt;
&lt;td&gt;1+ GB (configurable)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retention&lt;/td&gt;
&lt;td&gt;7 days&lt;/td&gt;
&lt;td&gt;30-365 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Users&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alerts&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dashboards&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API access&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data residency&lt;/td&gt;
&lt;td&gt;✅ (region-specific)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip: Enable Field Extraction Rules (FER)&lt;/strong&gt;: After first ingestion, create a FER for &lt;code&gt;_sourceCategory=aws/fsxn/audit&lt;/code&gt; with "Auto-parse JSON" enabled. This automatically extracts all JSON fields (UserName, Operation, ObjectName, etc.) as searchable metadata — no manual field definition needed. Go to &lt;strong&gt;Manage Data&lt;/strong&gt; → &lt;strong&gt;Logs&lt;/strong&gt; → &lt;strong&gt;Field Extraction Rules&lt;/strong&gt; → &lt;strong&gt;Add Rule&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For most PoC and small production deployments, the free tier is sufficient. Upgrade when you need longer retention or higher volume.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Residency &amp;amp; Classification
&lt;/h2&gt;

&lt;p&gt;Sumo Logic JP deployment keeps all data in Japan, but audit logs still contain PII fields:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Classification&lt;/th&gt;
&lt;th&gt;Sumo Logic Handling&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;UserName&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PII&lt;/td&gt;
&lt;td&gt;Use RBAC to restrict search access; consider field extraction rules for masking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ObjectName&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sensitive&lt;/td&gt;
&lt;td&gt;Path may reveal business context; restrict dashboard sharing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ClientIP&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Internal&lt;/td&gt;
&lt;td&gt;Generally acceptable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For APPI compliance considerations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data stays in JP region (no cross-border transfer for log data)&lt;/li&gt;
&lt;li&gt;Configure retention policies matching your regulatory requirements (7 days free tier vs 30-365 days paid)&lt;/li&gt;
&lt;li&gt;Implement Sumo Logic RBAC to restrict PII field access by role&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See the &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/data-classification.md" rel="noopener noreferrer"&gt;Data Classification Guide&lt;/a&gt; for full field classification and regulatory mapping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production Readiness
&lt;/h2&gt;

&lt;p&gt;This integration follows the project's &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations#production-readiness-levels--%E6%9C%AC%E7%95%AA%E6%BA%96%E5%82%99%E3%83%AC%E3%83%99%E3%83%AB" rel="noopener noreferrer"&gt;Production Readiness Levels&lt;/a&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;What You Get&lt;/th&gt;
&lt;th&gt;Go/No-Go to Next&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Level 1 (this Quick Start)&lt;/td&gt;
&lt;td&gt;Audit poller + DLQ&lt;/td&gt;
&lt;td&gt;Logs arrive, checkpoint advances, DLQ empty 24h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 2&lt;/td&gt;
&lt;td&gt;+ Sumo dashboards + alerts&lt;/td&gt;
&lt;td&gt;SLOs met 7 days, security review done&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 3&lt;/td&gt;
&lt;td&gt;+ DynamoDB ledger + poison-pill&lt;/td&gt;
&lt;td&gt;SLOs met 30 days, compliance pack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 4&lt;/td&gt;
&lt;td&gt;+ OTel Collector + redaction&lt;/td&gt;
&lt;td&gt;Multi-backend, PII redaction, DR tested&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Full criteria: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/pipeline-slo.md" rel="noopener noreferrer"&gt;Pipeline SLO Definitions&lt;/a&gt; | &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/runbooks/dlq-replay.md" rel="noopener noreferrer"&gt;DLQ Replay Runbook&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Enterprise scale&lt;/strong&gt;: For multi-account deployments across your Organization, see the &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/multi-account-deployment.md" rel="noopener noreferrer"&gt;StackSets deployment guide&lt;/a&gt;. For compliance evidence collection (ISMAP, FISC, SOC 2), see the &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/compliance-evidence-pack.md" rel="noopener noreferrer"&gt;Compliance Evidence Pack&lt;/a&gt;. For regulation-to-vendor retention mapping, see the &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/retention-policy-matrix.md" rel="noopener noreferrer"&gt;Retention Policy Matrix&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  CloudFormation Templates
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Template&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Key Parameters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;template.yaml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;FSx audit log poller&lt;/td&gt;
&lt;td&gt;S3AccessPointArn, SumoLogicHttpSourceSecretArn&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;template-ems.yaml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;EMS webhook handler&lt;/td&gt;
&lt;td&gt;SumoLogicHttpSourceSecretArn&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;template-fpolicy.yaml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;FPolicy EventBridge handler&lt;/td&gt;
&lt;td&gt;SumoLogicHttpSourceSecretArn, EventBusName&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/tree/main/integrations/sumo-logic" rel="noopener noreferrer"&gt;integrations/sumo-logic/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sumo Logic JP&lt;/strong&gt;: &lt;a href="https://service.jp.sumologic.com/" rel="noopener noreferrer"&gt;service.jp.sumologic.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP Source Docs&lt;/strong&gt;: &lt;a href="https://help.sumologic.com/docs/send-data/hosted-collectors/http-source/logs-metrics/" rel="noopener noreferrer"&gt;Configure HTTP Source&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search Query Language&lt;/strong&gt;: &lt;a href="https://help.sumologic.com/docs/search/search-query-language/" rel="noopener noreferrer"&gt;Search Operators&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Series GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/fsxn-observability-integrations&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Series Navigation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Part 1&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/why-your-fsx-for-ontap-audit-logs-deserve-better-than-ec2-kod"&gt;Why Your FSx for ONTAP Logs Deserve Better&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 2&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/shipping-fsx-for-ontap-logs-to-datadog-the-serverless-way-n9c"&gt;Shipping FSx for ONTAP Logs to Datadog — The Serverless Way&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 3&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/event-driven-ransomware-detection-with-ontap-arp-datadog-4cda"&gt;Event-Driven Ransomware Detection with ONTAP ARP + Datadog&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 4&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/fpolicy-file-activity-pipeline-ontap-to-datadog-via-ecs-fargate-2ing"&gt;FPolicy File Activity Pipeline — ONTAP to Datadog via ECS Fargate&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 5&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/escape-vendor-lock-in-multi-backend-log-delivery-with-otel-collector-for-fsx-for-ontap-2inb"&gt;Escape Vendor Lock-in: Multi-Backend Log Delivery with OTel Collector for FSx for ONTAP.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 6&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/direct-to-grafana-shipping-fsx-for-ontap-logs-to-grafana-cloud-loki-via-otlp-gateway-33hk"&gt;Direct-to-Grafana: Shipping FSx for ONTAP Logs to Grafana Cloud Loki via OTLP Gateway&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 7&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ship-fsx-for-ontap-audit-logs-to-new-relic-via-serverless-lambda-pipeline-3g87"&gt;Ship FSx for ONTAP Audit Logs to New Relic via Serverless Lambda Pipeline&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 8&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ec2-to-serverless-modernizing-fsx-for-ontap-splunk-integration-e8l"&gt;EC2 to Serverless: Modernizing FSx for ONTAP Splunk Integration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 9&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/data-sovereignty-fsx-for-ontap-logs-in-your-vpc-with-elastic-1mog"&gt;Data Sovereignty: FSx for ONTAP Logs in Your VPC with Elastic&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 10&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/high-cardinality-file-access-analysis-with-honeycomb-otel-1962"&gt;High-Cardinality File Access Analysis with Honeycomb + OTel&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 11&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ai-powered-root-cause-correlating-file-access-with-apm-via-dynatrace-4ffl"&gt;AI-Powered Root Cause: Correlating File Access with APM via Dynatrace&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 12&lt;/strong&gt;: FSx for ONTAP Audit Logs with Data Residency in your region with Sumo Logic (this post)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 13&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/9-services-one-architecture-what-we-learned-shipping-fsx-for-ontap-logs-to-every-major-19ig"&gt;9 Vendors, One Architecture&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Questions about the Sumo Logic JP integration or data residency? Drop a comment below.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/fsxn-observability-integrations&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>sumologic</category>
      <category>observability</category>
      <category>amazonfsxfornetappontap</category>
    </item>
    <item>
      <title>AI-Powered Root Cause: Correlating File Access with APM via Dynatrace</title>
      <dc:creator>Yoshiki Fujiwara(藤原 善基)@AWS Community Builder</dc:creator>
      <pubDate>Sun, 31 May 2026 00:26:51 +0000</pubDate>
      <link>https://dev.to/aws-builders/ai-powered-root-cause-correlating-file-access-with-apm-via-dynatrace-4ffl</link>
      <guid>https://dev.to/aws-builders/ai-powered-root-cause-correlating-file-access-with-apm-via-dynatrace-4ffl</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;We built a serverless Lambda pipeline that ships FSx for ONTAP audit logs to Dynatrace via the Log Ingest API v2. The real value: Dynatrace's Davis AI can automatically correlate file access anomalies with application performance degradation — answering "why is the app slow?" with "because 500 users hit the same NFS share simultaneously."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FSx for ONTAP → S3 Access Point → EventBridge Scheduler → Lambda → Dynatrace Log Ingest API v2
                                                                         │
                                                                         ▼
                                                                    Davis AI
                                                              ┌───────────────────┐
                                                              │ Correlates:       │
                                                              │ • File access     │
                                                              │   anomalies       │
                                                              │ • APM metrics     │
                                                              │ • Infrastructure  │
                                                              │   health          │
                                                              │                   │
                                                              │ → Root cause      │
                                                              │   in seconds      │
                                                              └───────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verified on Dynatrace SaaS Trial (Tokyo-equivalent region). Logs visible in Logs Viewer within 1-2 minutes.&lt;/p&gt;

&lt;p&gt;This is Part 11 of the &lt;a href="https://dev.to/aws-builders/why-your-fsx-for-ontap-audit-logs-deserve-better-than-ec2-kod"&gt;Serverless Observability for FSx for ONTAP&lt;/a&gt; series.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Dynatrace for FSx for ONTAP?
&lt;/h2&gt;

&lt;p&gt;Most observability tools treat storage logs as isolated data. Dynatrace is different — it builds a &lt;strong&gt;topology map&lt;/strong&gt; of your entire stack and uses Davis AI to find causal relationships through time-window correlation and entity connectivity:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Without Dynatrace&lt;/th&gt;
&lt;th&gt;With Dynatrace&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;App latency spike&lt;/td&gt;
&lt;td&gt;"Check the logs"&lt;/td&gt;
&lt;td&gt;Davis AI detects temporal correlation: file access to /vol/data/ increased 10x within the same 5-minute window as app response time degradation, connected via topology (app → NFS mount → SVM)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage I/O anomaly&lt;/td&gt;
&lt;td&gt;Manual investigation&lt;/td&gt;
&lt;td&gt;Automatic correlation via shared topology entities — Davis identifies which services are affected based on entity relationships&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User reports slow file access&lt;/td&gt;
&lt;td&gt;Grep through audit logs&lt;/td&gt;
&lt;td&gt;DQL query + topology view showing the full dependency path from user request to storage operation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The key differentiator: &lt;strong&gt;Davis AI correlates events across entities that share topology connections within overlapping time windows&lt;/strong&gt; — not just keyword matching or manual dashboard correlation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────┐
│ Event Sources                                           │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  EventBridge Scheduler                                  │
│  rate(5 minutes) ──→ Lambda                             │
│                       │ lists new files via             │
│                       │ S3 Access Point                 │
│                       │ (checkpoint in SSM)             │
│                       ▼                                 │
│           Dynatrace Log Ingest API v2                   │
│           (Api-Token auth)                              │
│                       │                                 │
│  EMS Webhook          │                                 │
│  ──→ API GW ──→ Lambda ─────────────┤                   │
│     (ems_handler)                   │                   │
│                                     ▼                   │
│  FPolicy                       Dynatrace                │
│  ──→ ECS Fargate ──→ SQS      (Logs Viewer,             │
│  ──→ Bridge Lambda              Davis AI,               │
│  ──→ EventBridge                DQL,                    │
│  ──→ Lambda (fpolicy_handler)   Dashboards)             │
│  ──────────────────────────────────────────────────────┤│
└─────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Davis AI: The Correlation Engine
&lt;/h2&gt;

&lt;p&gt;When you ship FSx for ONTAP logs to Dynatrace alongside your APM data, Davis AI can detect patterns like:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Storage contention → App slowdown&lt;/strong&gt;: Spike in file operations correlates with increased response times&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ransomware activity → Service impact&lt;/strong&gt;: ARP (Anti-Ransomware Protection) EMS events correlate with unusual file encryption patterns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quota exhaustion → Write failures&lt;/strong&gt;: ONTAP quota warnings correlate with application write errors&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This works because Dynatrace maps your FSx for ONTAP SVM as a &lt;strong&gt;custom device entity&lt;/strong&gt; in its topology, connecting it to the applications that access it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start (30 Minutes)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create Dynatrace API Token
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Log in to your Dynatrace environment&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Access Tokens&lt;/strong&gt; (Settings → Integration → Access tokens)&lt;/li&gt;
&lt;li&gt;Create a token with scope: &lt;strong&gt;&lt;code&gt;logs.ingest&lt;/code&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Token format: &lt;code&gt;dt0c01.&amp;lt;TOKEN_ID&amp;gt;.&amp;lt;TOKEN_SECRET&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2. Store Credentials
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws secretsmanager create-secret &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"dynatrace/fsxn-api-token"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--secret-string&lt;/span&gt; &lt;span class="s1"&gt;'{"api_token":"dt0c01.XXXXXXXX.YYYYYYYY"}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; ap-northeast-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Deploy CloudFormation Stack
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudformation deploy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--template-file&lt;/span&gt; integrations/dynatrace/template.yaml &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--stack-name&lt;/span&gt; fsxn-dynatrace-integration &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--parameter-overrides&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;S3AccessPointArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arn:aws:s3:ap-northeast-1:123456789012:accesspoint/fsxn-audit-ap &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;DynatraceApiTokenSecretArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:dynatrace/fsxn-api-token-XXXXXX &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;DynatraceEnvUrl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://abc12345.live.dynatrace.com &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;S3BucketName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;my-fsxn-audit-bucket &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--capabilities&lt;/span&gt; CAPABILITY_NAMED_IAM &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; ap-northeast-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Verify in Dynatrace
&lt;/h3&gt;

&lt;p&gt;Navigate to &lt;strong&gt;Logs&lt;/strong&gt; → &lt;strong&gt;View logs&lt;/strong&gt; → &lt;strong&gt;Run query&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fetch logs
| filter log.source == "fsxn-ontap"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Logs should appear within 1-2 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Log Entry Format
&lt;/h2&gt;

&lt;p&gt;Each audit log event is shipped with structured attributes for DQL querying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;EventID&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;4663&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;UserName&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;admin@corp.local&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,...}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"log.source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fsxn-ontap"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dt.source_entity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CUSTOM_DEVICE-fsxn-svm-prod-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-15T12:00:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fsxn.svm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"svm-prod-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fsxn.operation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ReadData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fsxn.user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"admin@corp.local"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fsxn.path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/vol/data/file.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fsxn.s3_key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"audit/2026/01/15/audit-001.json"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;dt.source_entity&lt;/code&gt; field links logs to a custom device in Dynatrace's topology, enabling Davis AI correlation.&lt;/p&gt;

&lt;h2&gt;
  
  
  DQL Query Examples
&lt;/h2&gt;

&lt;p&gt;Dynatrace Query Language (DQL) provides powerful analytics:&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic Investigation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// All failed file access attempts (using structured attributes)
fetch logs
| filter log.source == "fsxn-ontap"
| filter fsxn.result == "Failure"
| summarize count(), by: {fsxn.user, fsxn.path}

// Top operations by volume
fetch logs
| filter log.source == "fsxn-ontap"
| summarize count(), by: {fsxn.operation}
| sort count() desc

// Access timeline for a specific SVM
fetch logs
| filter fsxn.svm == "svm-prod-01"
| makeTimeseries count(), interval: 5m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  APM Correlation Queries
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File access volume vs app response time (side-by-side)
fetch logs
| filter log.source == "fsxn-ontap"
| makeTimeseries file_ops = count(), interval: 5m

// Correlate with service metrics in a dashboard
// (Place this next to a service response time tile)

// Find users causing the most I/O during a performance incident
fetch logs
| filter log.source == "fsxn-ontap"
| filter timestamp &amp;gt;= now() - 1h
| summarize ops = count(), by: {fsxn.user}
| sort ops desc
| limit 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Security Queries
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Detect potential ransomware (mass file modifications)
fetch logs
| filter log.source == "fsxn-ontap"
| filter fsxn.operation == "WriteData" OR fsxn.operation == "Delete"
| makeTimeseries write_ops = count(), interval: 1m
| filter write_ops &amp;gt; 100

// After-hours access
fetch logs
| filter log.source == "fsxn-ontap"
| filter hour(timestamp) &amp;lt; 7 OR hour(timestamp) &amp;gt; 19
| summarize count(), by: {fsxn.user, fsxn.path}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deployment Options
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Deployment&lt;/th&gt;
&lt;th&gt;URL Format&lt;/th&gt;
&lt;th&gt;Data Location&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SaaS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://&amp;lt;env-id&amp;gt;.live.dynatrace.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Dynatrace-managed (region-specific)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Managed&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://&amp;lt;your-domain&amp;gt;/e/&amp;lt;env-id&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your infrastructure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ActiveGate&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://&amp;lt;host&amp;gt;:9999/e/&amp;lt;env-id&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your network (proxy)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For data sovereignty requirements, Dynatrace Managed or ActiveGate keeps all data within your infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost Analysis
&lt;/h2&gt;

&lt;p&gt;Dynatrace pricing is based on Davis Data Units (DDU):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Monthly Log Volume&lt;/th&gt;
&lt;th&gt;DDU/day (est.)&lt;/th&gt;
&lt;th&gt;Monthly DDU Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1 GB&lt;/td&gt;
&lt;td&gt;~1 DDU&lt;/td&gt;
&lt;td&gt;Minimal (within base allocation)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10 GB&lt;/td&gt;
&lt;td&gt;~10 DDU&lt;/td&gt;
&lt;td&gt;~$25/month (at $2.50/DDU)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100 GB&lt;/td&gt;
&lt;td&gt;~100 DDU&lt;/td&gt;
&lt;td&gt;~$250/month&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Monthly Cost (10 GB/month)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lambda (5-min polling)&lt;/td&gt;
&lt;td&gt;~$3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EventBridge Scheduler&lt;/td&gt;
&lt;td&gt;~$1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secrets Manager&lt;/td&gt;
&lt;td&gt;~$1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dynatrace DDU&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~$25&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~$30&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;DDU pricing varies by contract. The 14-day trial includes generous DDU allocation for validation. Check your license terms for production estimates.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Gotchas &amp;amp; Lessons Learned
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Discovery&lt;/th&gt;
&lt;th&gt;Impact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;API returns HTTP 204 on success&lt;/strong&gt; (not 200)&lt;/td&gt;
&lt;td&gt;Lambda must treat 204 as success&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Trial environment has 1-2 minute ingestion lag&lt;/td&gt;
&lt;td&gt;Wait before checking Logs Viewer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;logs.ingest&lt;/code&gt; scope is required — &lt;code&gt;ReadConfig&lt;/code&gt;/&lt;code&gt;WriteConfig&lt;/code&gt; won't work&lt;/td&gt;
&lt;td&gt;Token creation must select correct scope&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;logs.read&lt;/code&gt; scope needed separately for API-based queries&lt;/td&gt;
&lt;td&gt;Create a second token for automation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Log entries older than 24 hours may be rejected&lt;/td&gt;
&lt;td&gt;Use current timestamps in test data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Max 1MB per request (smallest batch limit in this series)&lt;/td&gt;
&lt;td&gt;Lambda splits large batches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Firehose delivery requires ActiveGate (not direct to SaaS)&lt;/td&gt;
&lt;td&gt;Use Lambda direct for simplicity&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Davis AI Integration Pattern
&lt;/h2&gt;

&lt;p&gt;To get the most from Davis AI correlation, all three prerequisites must be in place:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ship FSx for ONTAP logs&lt;/strong&gt; (this integration) — with &lt;code&gt;dt.source_entity&lt;/code&gt; field set&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy OneAgent&lt;/strong&gt; on application hosts that access FSx for ONTAP via NFS/SMB — this creates the application-side topology&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create custom device&lt;/strong&gt; for each SVM (&lt;code&gt;dt.source_entity&lt;/code&gt;) — this creates the storage-side topology node. Use the &lt;a href="https://docs.dynatrace.com/docs/dynatrace-api/environment-api/entity-v2/post-custom-device" rel="noopener noreferrer"&gt;Entity API&lt;/a&gt; (&lt;code&gt;POST /api/v2/entities/custom&lt;/code&gt;) or Settings API to pre-create the device entity before first log ingestion&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites for correlation&lt;/strong&gt;: Davis AI correlation only activates when all three components are connected in the topology. Without OneAgent on the application hosts, Davis AI cannot establish the causal link between file access patterns and application performance. The custom device entity must use a consistent naming convention (e.g., &lt;code&gt;CUSTOM_DEVICE-fsxn-{svm-name}&lt;/code&gt;) across all log entries.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application (OneAgent) ──→ NFS/SMB ──→ FSx for ONTAP (SVM)
       │                                      │
       │ APM metrics                          │ Audit logs
       ▼                                      ▼
                    Dynatrace Davis AI
                    (automatic correlation)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Production Readiness
&lt;/h2&gt;

&lt;p&gt;This integration follows the project's &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations#production-readiness-levels--%E6%9C%AC%E7%95%AA%E6%BA%96%E5%82%99%E3%83%AC%E3%83%99%E3%83%AB" rel="noopener noreferrer"&gt;Production Readiness Levels&lt;/a&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;What You Get&lt;/th&gt;
&lt;th&gt;Go/No-Go to Next&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Level 1 (this Quick Start)&lt;/td&gt;
&lt;td&gt;Audit poller + DLQ&lt;/td&gt;
&lt;td&gt;Logs arrive, checkpoint advances, DLQ empty 24h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 2&lt;/td&gt;
&lt;td&gt;+ DQL dashboards + alerts&lt;/td&gt;
&lt;td&gt;SLOs met 7 days, security review done&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 3&lt;/td&gt;
&lt;td&gt;+ DynamoDB ledger + Davis AI correlation&lt;/td&gt;
&lt;td&gt;SLOs met 30 days, compliance pack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 4&lt;/td&gt;
&lt;td&gt;+ OTel Collector + redaction + OneAgent&lt;/td&gt;
&lt;td&gt;Multi-backend, PII redaction, full topology&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Data classification&lt;/strong&gt;: Dynatrace receives &lt;code&gt;fsxn.user&lt;/code&gt; and &lt;code&gt;fsxn.path&lt;/code&gt; fields (PII/sensitive). Dynatrace SaaS environments are region-specific — select a region matching your data residency requirements. For Managed/ActiveGate deployments, data stays in your infrastructure. See &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/data-classification.md" rel="noopener noreferrer"&gt;Data Classification Guide&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Full criteria: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/pipeline-slo.md" rel="noopener noreferrer"&gt;Pipeline SLO Definitions&lt;/a&gt; | &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/runbooks/dlq-replay.md" rel="noopener noreferrer"&gt;DLQ Replay Runbook&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CloudFormation Templates
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Template&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Key Parameters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;template.yaml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;FSx audit log poller&lt;/td&gt;
&lt;td&gt;S3AccessPointArn, DynatraceApiTokenSecretArn, DynatraceEnvUrl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;template-ems.yaml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;EMS webhook handler&lt;/td&gt;
&lt;td&gt;DynatraceApiTokenSecretArn, DynatraceEnvUrl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;template-fpolicy.yaml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;FPolicy EventBridge handler&lt;/td&gt;
&lt;td&gt;DynatraceApiTokenSecretArn, DynatraceEnvUrl, EventBusName&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/tree/main/integrations/dynatrace" rel="noopener noreferrer"&gt;integrations/dynatrace/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynatrace Log Ingest API&lt;/strong&gt;: &lt;a href="https://docs.dynatrace.com/docs/dynatrace-api/environment-api/log-monitoring-v2/post-ingest-logs" rel="noopener noreferrer"&gt;API v2 Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Davis AI&lt;/strong&gt;: &lt;a href="https://docs.dynatrace.com/docs/platform/davis-ai" rel="noopener noreferrer"&gt;Davis AI Overview&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DQL Reference&lt;/strong&gt;: &lt;a href="https://docs.dynatrace.com/docs/platform/grail/dynatrace-query-language" rel="noopener noreferrer"&gt;Dynatrace Query Language&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Series GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/fsxn-observability-integrations&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Series Navigation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Part 1&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/why-your-fsx-for-ontap-audit-logs-deserve-better-than-ec2-kod"&gt;Why Your FSx for ONTAP Logs Deserve Better&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 2&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/shipping-fsx-for-ontap-logs-to-datadog-the-serverless-way-n9c"&gt;Shipping FSx for ONTAP Logs to Datadog — The Serverless Way&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 3&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/event-driven-ransomware-detection-with-ontap-arp-datadog-4cda"&gt;Event-Driven Ransomware Detection with ONTAP ARP + Datadog&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 4&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/fpolicy-file-activity-pipeline-ontap-to-datadog-via-ecs-fargate-2ing"&gt;FPolicy File Activity Pipeline — ONTAP to Datadog via ECS Fargate&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 5&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/escape-vendor-lock-in-multi-backend-log-delivery-with-otel-collector-for-fsx-for-ontap-2inb"&gt;Escape Vendor Lock-in: Multi-Backend Log Delivery with OTel Collector for FSx for ONTAP.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 6&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/direct-to-grafana-shipping-fsx-for-ontap-logs-to-grafana-cloud-loki-via-otlp-gateway-33hk"&gt;Direct-to-Grafana: Shipping FSx for ONTAP Logs to Grafana Cloud Loki via OTLP Gateway&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 7&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ship-fsx-for-ontap-audit-logs-to-new-relic-via-serverless-lambda-pipeline-3g87"&gt;Ship FSx for ONTAP Audit Logs to New Relic via Serverless Lambda Pipeline&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 8&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ec2-to-serverless-modernizing-fsx-for-ontap-splunk-integration-e8l"&gt;EC2 to Serverless: Modernizing FSx for ONTAP Splunk Integration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 9&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/data-sovereignty-fsx-for-ontap-logs-in-your-vpc-with-elastic-1mog"&gt;Data Sovereignty: FSx for ONTAP Logs in Your VPC with Elastic&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 10&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/high-cardinality-file-access-analysis-with-honeycomb-otel-1962"&gt;High-Cardinality File Access Analysis with Honeycomb + OTel&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 11&lt;/strong&gt;: AI-Powered Root Cause with Dynatrace (this post)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 12&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/fsx-for-ontap-audit-logs-with-data-residency-in-your-region-46e6"&gt;FSx for ONTAP Audit Logs with Data Residency in your region with Sumo Logic&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 13&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/9-services-one-architecture-what-we-learned-shipping-fsx-for-ontap-logs-to-every-major-19ig"&gt;9 Vendors, One Architecture&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Questions about the Dynatrace integration or Davis AI correlation? Drop a comment below.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/fsxn-observability-integrations&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>dynatrace</category>
      <category>observability</category>
      <category>amazonfsxfornetappontap</category>
    </item>
    <item>
      <title>High-Cardinality File Access Analysis with Honeycomb + OTel</title>
      <dc:creator>Yoshiki Fujiwara(藤原 善基)@AWS Community Builder</dc:creator>
      <pubDate>Sun, 31 May 2026 00:15:53 +0000</pubDate>
      <link>https://dev.to/aws-builders/high-cardinality-file-access-analysis-with-honeycomb-otel-1962</link>
      <guid>https://dev.to/aws-builders/high-cardinality-file-access-analysis-with-honeycomb-otel-1962</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;We built a serverless pipeline that ships FSx for ONTAP audit logs to Honeycomb, where its high-cardinality query engine turns file access data into actionable insights. Two delivery paths verified:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Path A: Direct]
FSx for ONTAP → S3 Access Point → EventBridge Scheduler → Lambda → Honeycomb Events Batch API

[Path B: OTel Collector]
FSx for ONTAP → S3 Access Point → EventBridge Scheduler → Lambda → OTel Collector → OTLP → Honeycomb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why Honeycomb for file access logs? Because file access data is inherently &lt;strong&gt;high-cardinality&lt;/strong&gt;: thousands of users × millions of file paths × dozens of operations × multiple SVMs. Traditional log tools force you to pre-aggregate or sample. Honeycomb lets you query the raw events at full resolution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────────────┐
│  Honeycomb Query Engine                              │
│                                                      │
│  "Show me which users accessed /vol/finance/*        │
│   between 2am-4am last Tuesday"                      │
│                                                      │
│  → BubbleUp: auto-detect anomalous dimensions        │
│  → Heatmap: visualize access density over time       │
│  → GROUP BY user, path, operation — no pre-indexing  │
│                                                      │
│  20M events/month FREE                               │
└──────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is Part 10 of the &lt;a href="https://dev.to/aws-builders/why-your-fsx-for-ontap-audit-logs-deserve-better-than-ec2-kod"&gt;Serverless Observability for FSx for ONTAP&lt;/a&gt; series.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Honeycomb for File Access Logs?
&lt;/h2&gt;

&lt;p&gt;Most observability tools index a fixed set of fields. When you have high-cardinality dimensions — like file paths (&lt;code&gt;/vol/data/project-alpha/2026/Q1/report-final-v3.docx&lt;/code&gt;) or Active Directory usernames — you hit index bloat, slow queries, or forced sampling.&lt;/p&gt;

&lt;p&gt;Honeycomb's columnar storage handles this natively:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Traditional Logs&lt;/th&gt;
&lt;th&gt;Honeycomb&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Query by arbitrary field&lt;/td&gt;
&lt;td&gt;Pre-index or full scan&lt;/td&gt;
&lt;td&gt;Instant (columnar)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GROUP BY high-cardinality field&lt;/td&gt;
&lt;td&gt;Expensive / limited&lt;/td&gt;
&lt;td&gt;Native&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BubbleUp (anomaly detection)&lt;/td&gt;
&lt;td&gt;Manual investigation&lt;/td&gt;
&lt;td&gt;Semi-automatic (select time range, BubbleUp identifies differing dimensions)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heatmap visualization&lt;/td&gt;
&lt;td&gt;Requires pre-aggregation&lt;/td&gt;
&lt;td&gt;Raw events&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For FSx for ONTAP audit logs, this means you can ask questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Which users accessed the most files in the last hour?" (GROUP BY user)&lt;/li&gt;
&lt;li&gt;"What's different about the spike at 3am?" (BubbleUp)&lt;/li&gt;
&lt;li&gt;"Show me the access pattern heatmap for /vol/finance/" (Heatmap)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────┐
│ Event Sources                                           │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  EventBridge Scheduler                                  │
│  rate(5 minutes) ──→ Lambda                             │
│                       │ lists new files via             │
│                       │ S3 Access Point                 │
│                       │ (checkpoint in SSM)             │
│                       ▼                                 │
│              Honeycomb Events Batch API                 │
│              (x-honeycomb-team header)                  │
│                       │                                 │
│  EMS Webhook          │                                 │
│  ──→ API GW ──→ Lambda ─────────────┤                   │
│     (ems_handler)                   │                   │
│                                     ▼                   │
│  FPolicy                        Honeycomb               │
│  ──→ ECS Fargate ──→ SQS       (BubbleUp,               │
│  ──→ Bridge Lambda               Heatmap,               │
│  ──→ EventBridge                 Explore)               │
│  ──→ Lambda (fpolicy_handler) ──────────────────────────┤
└─────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Two Verified Delivery Paths
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Path A: Direct Events Batch API
&lt;/h3&gt;

&lt;p&gt;Simplest path. Lambda sends events directly to Honeycomb's Events Batch API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Batch format
&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;time&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2026-01-15T12:00:00Z&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;source&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fsxn-ontap&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;service&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ontap-audit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;event_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4663&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;svm&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;svm-prod-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;admin@corp.local&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;operation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ReadData&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/vol/data/file.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;result&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Success&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;client_ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10.0.x.x&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Path B: OTel Collector (OTLP)
&lt;/h3&gt;

&lt;p&gt;For multi-backend delivery or when you want enrichment/redaction in the pipeline. Verified in &lt;a href="https://dev.to/aws-builders/escape-vendor-lock-in-multi-backend-log-delivery-with-otel-collector-for-fsx-for-ontap"&gt;Part 5&lt;/a&gt; with Honeycomb as one of the backends.&lt;/p&gt;

&lt;p&gt;The OTel Collector uses the &lt;code&gt;otlp_http&lt;/code&gt; exporter with &lt;code&gt;x-honeycomb-dataset&lt;/code&gt; header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;exporters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;otlphttp/honeycomb&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://api.honeycomb.io&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;x-honeycomb-team&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${HONEYCOMB_API_KEY}&lt;/span&gt;
      &lt;span class="na"&gt;x-honeycomb-dataset&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fsxn-audit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Quick Start (30 Minutes)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Get a Honeycomb Ingest Key
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Sign up at &lt;a href="https://www.honeycomb.io/" rel="noopener noreferrer"&gt;honeycomb.io&lt;/a&gt; (free tier: 20M events/month)&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Account&lt;/strong&gt; → &lt;strong&gt;Team Settings&lt;/strong&gt; → &lt;strong&gt;API Keys&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Create an &lt;strong&gt;Ingest Key&lt;/strong&gt; (starts with &lt;code&gt;hcaik_&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Critical&lt;/strong&gt;: You MUST use an &lt;strong&gt;Ingest Key&lt;/strong&gt; (&lt;code&gt;hcaik_*&lt;/code&gt;). Environment Keys (&lt;code&gt;hcxik_*&lt;/code&gt;) will be rejected.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Store Credentials
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws secretsmanager create-secret &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"honeycomb/fsxn-api-key"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--secret-string&lt;/span&gt; &lt;span class="s1"&gt;'{"api_key":"hcaik_01abc..."}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; ap-northeast-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Deploy CloudFormation Stack
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudformation deploy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--template-file&lt;/span&gt; integrations/honeycomb/template.yaml &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--stack-name&lt;/span&gt; fsxn-honeycomb-integration &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--parameter-overrides&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;S3AccessPointArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arn:aws:s3:ap-northeast-1:123456789012:accesspoint/fsxn-audit-ap &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;HoneycombApiKeySecretArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:honeycomb/fsxn-api-key-XXXXXX &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;HoneycombDataset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;fsxn-audit &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;S3BucketName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;my-fsxn-audit-bucket &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--capabilities&lt;/span&gt; CAPABILITY_NAMED_IAM &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; ap-northeast-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Verify in Honeycomb
&lt;/h3&gt;

&lt;p&gt;Navigate to your dataset → Explore Data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;"ontap-audit"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Events should appear within seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honeycomb Query Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Basic Investigation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="k"&gt;All&lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt; &lt;span class="k"&gt;access&lt;/span&gt; &lt;span class="n"&gt;attempts&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;"Failure"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Top&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="k"&gt;access&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Operations&lt;/span&gt; &lt;span class="n"&gt;breakdown&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;operation&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  High-Cardinality Analysis (Honeycomb's Strength)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="n"&gt;BubbleUp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;What&lt;/span&gt;&lt;span class="s1"&gt;'s different about the 3am spike?
# Select the spike in the time series → click BubbleUp
# Honeycomb auto-identifies which dimensions differ

# Heatmap: Access density by hour
WHERE operation = "ReadData" | HEATMAP(timestamp)

# Trace a specific user'&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;activity&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;"admin@corp.local"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;VISUALIZE&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Find&lt;/span&gt; &lt;span class="n"&gt;unusual&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="k"&gt;access&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Security Investigation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="k"&gt;After&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hours&lt;/span&gt; &lt;span class="k"&gt;access&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="k"&gt;sensitive&lt;/span&gt; &lt;span class="n"&gt;paths&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="k"&gt;CONTAINS&lt;/span&gt; &lt;span class="nv"&gt;"confidential"&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;hour&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;BETWEEN&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Users&lt;/span&gt; &lt;span class="n"&gt;accessing&lt;/span&gt; &lt;span class="n"&gt;paths&lt;/span&gt; &lt;span class="n"&gt;they&lt;/span&gt; &lt;span class="n"&gt;haven&lt;/span&gt;&lt;span class="s1"&gt;'t accessed before
# (Use Honeycomb'&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="nv"&gt;"compare to baseline"&lt;/span&gt; &lt;span class="n"&gt;feature&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Bulk&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;operations&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;potential&lt;/span&gt; &lt;span class="n"&gt;exfiltration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;operation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;"ReadData"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Event Schema (13 Fields)
&lt;/h2&gt;

&lt;p&gt;All fields are queryable at full cardinality without pre-indexing:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Cardinality&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;source&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;fsxn-ontap&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;service&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ontap-audit&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;event_type&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4663&lt;/td&gt;
&lt;td&gt;Low (~10 types)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;svm&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;svm-prod-01&lt;/td&gt;
&lt;td&gt;Low (~5-20)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;user&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="mailto:admin@corp.local"&gt;admin@corp.local&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;High&lt;/strong&gt; (thousands)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;operation&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ReadData&lt;/td&gt;
&lt;td&gt;Low (~10 types)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;path&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;/vol/data/report.pdf&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Very High&lt;/strong&gt; (millions)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;result&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Success / Failure&lt;/td&gt;
&lt;td&gt;Low (2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;client_ip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10.0.x.x&lt;/td&gt;
&lt;td&gt;Medium (hundreds)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;s3_key&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;audit/svm-prod-01/2026/...&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Very High&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Cost Analysis
&lt;/h2&gt;

&lt;p&gt;Honeycomb pricing is event-based, not volume-based:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Monthly Log Volume&lt;/th&gt;
&lt;th&gt;Estimated Events&lt;/th&gt;
&lt;th&gt;Honeycomb Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1 GB&lt;/td&gt;
&lt;td&gt;~500K events&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Free&lt;/strong&gt; (20M/month included)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10 GB&lt;/td&gt;
&lt;td&gt;~5M events&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Free&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;30 GB&lt;/td&gt;
&lt;td&gt;~15M events&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Free&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50 GB&lt;/td&gt;
&lt;td&gt;~25M events&lt;/td&gt;
&lt;td&gt;Paid tier (~$100/month)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Monthly Cost (10 GB/month)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lambda (5-min polling)&lt;/td&gt;
&lt;td&gt;~$3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EventBridge Scheduler&lt;/td&gt;
&lt;td&gt;~$1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secrets Manager&lt;/td&gt;
&lt;td&gt;~$1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Honeycomb&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Free&lt;/strong&gt; (5M events &amp;lt; 20M limit)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~$5&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;The 20M events/month free tier covers most FSx for ONTAP deployments. Estimate ~500 events per MB of audit log data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Gotchas &amp;amp; Lessons Learned
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Discovery&lt;/th&gt;
&lt;th&gt;Impact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Must use Ingest Key (&lt;code&gt;hcaik_*&lt;/code&gt;)&lt;/strong&gt; — Environment Key (&lt;code&gt;hcxik_*&lt;/code&gt;) is silently rejected&lt;/td&gt;
&lt;td&gt;Events disappear without error if wrong key type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Events with timestamps older than ~4 hours are rejected&lt;/td&gt;
&lt;td&gt;Test data must use current timestamps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;5MB max request body size; our implementation batches in chunks of 100 events for reliability&lt;/td&gt;
&lt;td&gt;Lambda splits large files into multiple requests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Honeycomb processes data in US regions only&lt;/td&gt;
&lt;td&gt;Evaluate cross-border data transfer requirements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Dataset auto-created on first event if it doesn't exist&lt;/td&gt;
&lt;td&gt;No pre-provisioning needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;OTel Collector path requires &lt;code&gt;x-honeycomb-dataset&lt;/code&gt; header&lt;/td&gt;
&lt;td&gt;Without it, events go to a default dataset&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Direct vs OTel Collector: When to Use Which
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criteria&lt;/th&gt;
&lt;th&gt;Direct (Path A)&lt;/th&gt;
&lt;th&gt;OTel Collector (Path B)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Simplicity&lt;/td&gt;
&lt;td&gt;✅ Fewer components&lt;/td&gt;
&lt;td&gt;More infrastructure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-backend&lt;/td&gt;
&lt;td&gt;❌ Honeycomb only&lt;/td&gt;
&lt;td&gt;✅ Any OTLP backend&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enrichment/redaction&lt;/td&gt;
&lt;td&gt;❌ In Lambda only&lt;/td&gt;
&lt;td&gt;✅ Collector processors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost&lt;/td&gt;
&lt;td&gt;Lower (no Collector)&lt;/td&gt;
&lt;td&gt;Collector compute cost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recommendation&lt;/td&gt;
&lt;td&gt;Single-backend PoC&lt;/td&gt;
&lt;td&gt;Production multi-backend&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note from Honeycomb&lt;/strong&gt;: Honeycomb recommends OTLP as the primary ingest path for new production deployments. The Events Batch API (Path A) remains fully supported and is simpler for single-backend PoCs. If you start with Path A, migrating to Path B (OTLP) requires no changes to your Honeycomb queries — only the delivery mechanism changes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Production Readiness
&lt;/h2&gt;

&lt;p&gt;This integration follows the project's &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations#production-readiness-levels--%E6%9C%AC%E7%95%AA%E6%BA%96%E5%82%99%E3%83%AC%E3%83%99%E3%83%AB" rel="noopener noreferrer"&gt;Production Readiness Levels&lt;/a&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;What You Get&lt;/th&gt;
&lt;th&gt;Go/No-Go to Next&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Level 1 (this Quick Start)&lt;/td&gt;
&lt;td&gt;Audit poller + DLQ&lt;/td&gt;
&lt;td&gt;Logs arrive, checkpoint advances, DLQ empty 24h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 2&lt;/td&gt;
&lt;td&gt;+ Honeycomb queries + alerts&lt;/td&gt;
&lt;td&gt;SLOs met 7 days, security review done&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 3&lt;/td&gt;
&lt;td&gt;+ DynamoDB ledger + poison-pill&lt;/td&gt;
&lt;td&gt;SLOs met 30 days, compliance pack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 4&lt;/td&gt;
&lt;td&gt;+ OTel Collector + redaction&lt;/td&gt;
&lt;td&gt;Multi-backend, PII redaction, DR tested&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Data classification note&lt;/strong&gt;: Honeycomb receives &lt;code&gt;user&lt;/code&gt; and &lt;code&gt;path&lt;/code&gt; fields which are classified as PII/sensitive. Since Honeycomb processes data in US regions only, evaluate cross-border transfer requirements. For PII-sensitive deployments, use the OTel Collector path (Path B) with redaction processors. See &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/data-classification.md" rel="noopener noreferrer"&gt;Data Classification Guide&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Full criteria: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/pipeline-slo.md" rel="noopener noreferrer"&gt;Pipeline SLO Definitions&lt;/a&gt; | &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/runbooks/dlq-replay.md" rel="noopener noreferrer"&gt;DLQ Replay Runbook&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CloudFormation Templates
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Template&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Key Parameters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;template.yaml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;FSx audit log poller&lt;/td&gt;
&lt;td&gt;S3AccessPointArn, HoneycombApiKeySecretArn, HoneycombDataset&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;template-ems.yaml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;EMS webhook handler&lt;/td&gt;
&lt;td&gt;HoneycombApiKeySecretArn, HoneycombDataset&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;template-fpolicy.yaml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;FPolicy EventBridge handler&lt;/td&gt;
&lt;td&gt;HoneycombApiKeySecretArn, HoneycombDataset, EventBusName&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/tree/main/integrations/honeycomb" rel="noopener noreferrer"&gt;integrations/honeycomb/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OTel Collector path&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/tree/main/integrations/otel-collector" rel="noopener noreferrer"&gt;integrations/otel-collector/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Honeycomb Docs&lt;/strong&gt;: &lt;a href="https://docs.honeycomb.io/" rel="noopener noreferrer"&gt;docs.honeycomb.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Honeycomb BubbleUp&lt;/strong&gt;: &lt;a href="https://docs.honeycomb.io/investigate/bubbleup/" rel="noopener noreferrer"&gt;BubbleUp Guide&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Series GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/fsxn-observability-integrations&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Series Navigation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Part 1&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/why-your-fsx-for-ontap-audit-logs-deserve-better-than-ec2-kod"&gt;Why Your FSx for ONTAP Logs Deserve Better&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 2&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/shipping-fsx-for-ontap-logs-to-datadog-the-serverless-way-n9c"&gt;Shipping FSx for ONTAP Logs to Datadog — The Serverless Way&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 3&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/event-driven-ransomware-detection-with-ontap-arp-datadog-4cda"&gt;Event-Driven Ransomware Detection with ONTAP ARP + Datadog&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 4&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/fpolicy-file-activity-pipeline-ontap-to-datadog-via-ecs-fargate-2ing"&gt;FPolicy File Activity Pipeline — ONTAP to Datadog via ECS Fargate&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 5&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/escape-vendor-lock-in-multi-backend-log-delivery-with-otel-collector-for-fsx-for-ontap-2inb"&gt;Escape Vendor Lock-in: Multi-Backend Log Delivery with OTel Collector for FSx for ONTAP.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 6&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/direct-to-grafana-shipping-fsx-for-ontap-logs-to-grafana-cloud-loki-via-otlp-gateway-33hk"&gt;Direct-to-Grafana: Shipping FSx for ONTAP Logs to Grafana Cloud Loki via OTLP Gateway&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 7&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ship-fsx-for-ontap-audit-logs-to-new-relic-via-serverless-lambda-pipeline-3g87"&gt;Ship FSx for ONTAP Audit Logs to New Relic via Serverless Lambda Pipeline&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 8&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ec2-to-serverless-modernizing-fsx-for-ontap-splunk-integration-e8l"&gt;EC2 to Serverless: Modernizing FSx for ONTAP Splunk Integration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 9&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/data-sovereignty-fsx-for-ontap-logs-in-your-vpc-with-elastic-1mog"&gt;Data Sovereignty: FSx for ONTAP Logs in Your VPC with Elastic&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 10&lt;/strong&gt;: High-Cardinality File Access Analysis with Honeycomb (this post)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 11&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ai-powered-root-cause-correlating-file-access-with-apm-via-dynatrace-4ffl"&gt;AI-Powered Root Cause: Correlating File Access with APM via Dynatrace&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 12&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/fsx-for-ontap-audit-logs-with-data-residency-in-your-region-46e6"&gt;FSx for ONTAP Audit Logs with Data Residency in your region with Sumo Logic&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 13&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/9-services-one-architecture-what-we-learned-shipping-fsx-for-ontap-logs-to-every-major-19ig"&gt;9 Vendors, One Architecture&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Questions about high-cardinality analysis or the Honeycomb integration? Drop a comment below.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/fsxn-observability-integrations&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>honeycomb</category>
      <category>observability</category>
      <category>amazonfsxfornetappontap</category>
    </item>
    <item>
      <title>Data Sovereignty: FSx for ONTAP Logs in Your VPC with Elastic</title>
      <dc:creator>Yoshiki Fujiwara(藤原 善基)@AWS Community Builder</dc:creator>
      <pubDate>Sun, 31 May 2026 00:08:55 +0000</pubDate>
      <link>https://dev.to/aws-builders/data-sovereignty-fsx-for-ontap-logs-in-your-vpc-with-elastic-1mog</link>
      <guid>https://dev.to/aws-builders/data-sovereignty-fsx-for-ontap-logs-in-your-vpc-with-elastic-1mog</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;We built a serverless Lambda pipeline that ships FSx for ONTAP audit logs to Elasticsearch via the Bulk API, with Elastic Common Schema (ECS) field mapping for native Kibana SIEM compatibility. Verified on Elastic Cloud Serverless (Tokyo, AWS).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FSx for ONTAP → S3 Access Point → EventBridge Scheduler → Lambda → Elasticsearch Bulk API
                                                                      │
                                                          ┌───────────┴───────────┐
                                                          │                       │
                                                   Elastic Cloud            Self-hosted
                                                   Serverless (Tokyo)       (VPC / EKS)
                                                          │                       │
                                                          ▼                       ▼
                                                       Kibana                  Kibana
                                                    (SIEM / Discover)      (full control)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three deployment options — same Lambda, same ECS mapping, same KQL queries:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Data Location&lt;/th&gt;
&lt;th&gt;Ops Burden&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Elastic Cloud Serverless&lt;/td&gt;
&lt;td&gt;Elastic-managed (Tokyo)&lt;/td&gt;
&lt;td&gt;Zero&lt;/td&gt;
&lt;td&gt;Fast PoC, small teams&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Elastic Cloud Dedicated&lt;/td&gt;
&lt;td&gt;Elastic-managed (region choice)&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Production, compliance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted (EC2/EKS in VPC)&lt;/td&gt;
&lt;td&gt;Your VPC&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Data sovereignty, air-gapped&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is Part 9 of the &lt;a href="https://dev.to/aws-builders/why-your-fsx-for-ontap-audit-logs-deserve-better-than-ec2-kod"&gt;Serverless Observability for FSx for ONTAP&lt;/a&gt; series.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Elastic for FSx for ONTAP?
&lt;/h2&gt;

&lt;p&gt;If your organization has &lt;strong&gt;data sovereignty requirements&lt;/strong&gt; — public sector, financial services, healthcare — you need to control where your audit logs live. Elastic gives you that choice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Self-hosted in your VPC&lt;/strong&gt;: Zero data leaves your network boundary&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elastic Cloud in Tokyo&lt;/strong&gt;: Managed service with regional data residency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ECS field mapping&lt;/strong&gt;: Native compatibility with Kibana Security SIEM rules&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Elastic Common Schema mapping means your FSx for ONTAP audit logs work with Kibana's built-in detection rules, dashboards, and SIEM workflows without custom parsing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────┐
│ Event Sources                                           │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  EventBridge Scheduler                                  │
│  rate(5 minutes) ──→ Lambda                             │
│                       │ lists new files via             │
│                       │ S3 Access Point                 │
│                       │ (checkpoint in SSM)             │
│                       ▼                                 │
│              Elasticsearch Bulk API                     │
│              (ECS field mapping)                        │
│                       │                                 │
│  EMS Webhook          │                                 │
│  ──→ API GW ──→ Lambda ─────────────┤                   │
│     (ems_handler)                   │                   │
│                                     ▼                   │
│  FPolicy                         Kibana                 │
│  ──→ ECS Fargate ──→ SQS        (Discover,              │
│  ──→ Bridge Lambda                SIEM,                 │
│  ──→ EventBridge                  Dashboard)            │
│  ──→ Lambda (fpolicy_handler) ──────────────────────────┤
└─────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ECS Field Mapping: Why It Matters
&lt;/h2&gt;

&lt;p&gt;Our Lambda maps FSx for ONTAP audit fields to Elastic Common Schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-15T12:00:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4663"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"access"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"admin@corp.local"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"10.0.x.x"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fsxn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"operation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ReadData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/vol/data/confidential/report.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"svm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"svm-prod-01"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cloud"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"aws"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fsx-ontap"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;event.code&lt;/code&gt; maps Windows Event IDs for SIEM correlation (ECS-compliant)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;event.type&lt;/code&gt; and &lt;code&gt;event.category&lt;/code&gt; enable Kibana Security's detection rules&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;user.name&lt;/code&gt; works with Kibana Security's user activity dashboards&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;source.ip&lt;/code&gt; integrates with threat intelligence feeds&lt;/li&gt;
&lt;li&gt;Daily indices (&lt;code&gt;fsxn-audit-YYYY.MM.DD&lt;/code&gt;) support ILM for retention policies&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Data Streams (Elastic 8.x+)&lt;/strong&gt;: For new deployments, consider using &lt;a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/data-streams.html" rel="noopener noreferrer"&gt;Data Streams&lt;/a&gt; instead of daily indices. Data Streams handle rollover automatically and simplify ILM configuration. Our template supports both patterns.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Quick Start (30 Minutes)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create Elastic Cloud Serverless Project
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Sign up at &lt;a href="https://cloud.elastic.co/" rel="noopener noreferrer"&gt;cloud.elastic.co&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create an &lt;strong&gt;Elasticsearch Serverless&lt;/strong&gt; project&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;AWS&lt;/strong&gt; as cloud provider, &lt;strong&gt;ap-northeast-1 (Tokyo)&lt;/strong&gt; as region&lt;/li&gt;
&lt;li&gt;Create an API Key: Kibana → Stack Management → Security → API Keys

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimum required privilege&lt;/strong&gt;: Grant only &lt;code&gt;index&lt;/code&gt; privilege on &lt;code&gt;fsxn-audit-*&lt;/code&gt; indices with &lt;code&gt;write&lt;/code&gt; and &lt;code&gt;create_index&lt;/code&gt; actions. Do not use a superuser key.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2. Store Credentials
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# API Key is in Base64-encoded format (id:key)&lt;/span&gt;
&lt;span class="c"&gt;# The key should have ONLY index:write scope on fsxn-audit-* indices&lt;/span&gt;
aws secretsmanager create-secret &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"elastic/fsxn-api-key"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--secret-string&lt;/span&gt; &lt;span class="s1"&gt;'{"api_key":"&amp;lt;base64_encoded_id:api_key&amp;gt;"}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; ap-northeast-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Deploy CloudFormation Stack
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudformation deploy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--template-file&lt;/span&gt; integrations/elastic/template.yaml &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--stack-name&lt;/span&gt; fsxn-elastic-integration &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--parameter-overrides&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;S3AccessPointArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arn:aws:s3:ap-northeast-1:123456789012:accesspoint/fsxn-audit-ap &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;ElasticApiKeySecretArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:elastic/fsxn-api-key-XXXXXX &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;ElasticEndpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://my-project.es.ap-northeast-1.aws.elastic.cloud:443 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;S3BucketName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;my-fsxn-audit-bucket &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--capabilities&lt;/span&gt; CAPABILITY_NAMED_IAM &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; ap-northeast-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Verify in Kibana
&lt;/h3&gt;

&lt;p&gt;Navigate to Kibana → Discover → select &lt;code&gt;fsxn-audit-*&lt;/code&gt; index pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;fsxn.result&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Failure"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see audit log documents with ECS-mapped fields within minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Index Template (Recommended)
&lt;/h2&gt;

&lt;p&gt;Create this index template before first ingestion for optimal field types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;PUT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;_index_template/fsxn-audit&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"index_patterns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"fsxn-audit-*"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"template"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"settings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"number_of_replicas"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"index.lifecycle.name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fsxn-audit-policy"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mappings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"@timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"event.code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"keyword"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"event.type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"keyword"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"event.category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"keyword"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"user.name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"keyword"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"source.ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ip"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"fsxn.operation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"keyword"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"fsxn.path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"fields"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"keyword"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"keyword"&lt;/span&gt;&lt;span class="p"&gt;}}},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"fsxn.result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"keyword"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"fsxn.svm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"keyword"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"cloud.provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"keyword"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"cloud.service.name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"keyword"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ILM Policy (Recommended)
&lt;/h3&gt;

&lt;p&gt;Create this ILM policy to manage index lifecycle automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;PUT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;_ilm/policy/fsxn-audit-policy&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"phases"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"hot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"min_age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0ms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"actions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"rollover"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"max_age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"max_primary_shard_size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"50gb"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"warm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"min_age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"7d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"actions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"shrink"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"number_of_shards"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"forcemerge"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"max_num_segments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"cold"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"min_age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"30d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"actions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"delete"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"min_age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"90d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"actions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"delete"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Adjust retention periods based on your regulatory requirements. See the &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/retention-policy-matrix.md" rel="noopener noreferrer"&gt;Retention Policy Matrix&lt;/a&gt; for regulation-specific guidance (FISC: 7 years, ISMAP: 1 year, SOC 2: 1 year).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  KQL Query Examples
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# All failed access attempts&lt;/span&gt;
&lt;span class="na"&gt;fsxn.result&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Failure"&lt;/span&gt;

&lt;span class="c1"&gt;# Specific user activity&lt;/span&gt;
&lt;span class="na"&gt;user.name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;admin@corp.local"&lt;/span&gt; &lt;span class="na"&gt;AND fsxn.operation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;WriteData"&lt;/span&gt;

&lt;span class="c1"&gt;# File access by path pattern (sensitive directories)&lt;/span&gt;
&lt;span class="na"&gt;fsxn.path: *confidential* OR fsxn.path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*restricted&lt;/span&gt;&lt;span class="err"&gt;*&lt;/span&gt;

&lt;span class="c1"&gt;# Operations by SVM (using event.code for Windows Event ID)&lt;/span&gt;
&lt;span class="na"&gt;fsxn.svm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;svm-prod-01"&lt;/span&gt; &lt;span class="na"&gt;AND event.code&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4663"&lt;/span&gt;

&lt;span class="c1"&gt;# Delete operations (potential data exfiltration)&lt;/span&gt;
&lt;span class="na"&gt;fsxn.operation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Delete"&lt;/span&gt; &lt;span class="na"&gt;AND NOT user.name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;backup-svc@corp.local"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Kibana SIEM Integration
&lt;/h2&gt;

&lt;p&gt;With ECS mapping, you can create detection rules in Kibana Security:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rule&lt;/th&gt;
&lt;th&gt;Condition&lt;/th&gt;
&lt;th&gt;Severity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mass file deletion&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;fsxn.operation: "Delete"&lt;/code&gt; count &amp;gt; 50 in 5m&lt;/td&gt;
&lt;td&gt;Critical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;After-hours access&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;@timestamp&lt;/code&gt; outside business hours + &lt;code&gt;fsxn.result: "Success"&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unauthorized path access&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;fsxn.path: *restricted*&lt;/code&gt; AND &lt;code&gt;fsxn.result: "Failure"&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New user first access&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;user.name&lt;/code&gt; not seen in last 30 days&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Self-Hosted Option: Data Never Leaves Your VPC
&lt;/h2&gt;

&lt;p&gt;For maximum data sovereignty, deploy Elasticsearch in your VPC:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lambda (VPC) ──→ Elasticsearch (VPC, private subnet)
                        │
                        ▼
                 Kibana (VPC, private subnet + ALB)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploy Lambda in the same VPC with security group rules allowing port 9200 to the Elasticsearch cluster.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Network path consideration&lt;/strong&gt;: If this Lambda also reads from the FSx for ONTAP S3 Access Point, a NAT Gateway is required (S3 AP access from VPC requires internet-routed path — see &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/s3ap-fsxn-specification.md" rel="noopener noreferrer"&gt;S3 AP Specification&lt;/a&gt;). For the self-hosted pattern, consider splitting into two Lambdas: one outside VPC for S3 AP reads, and one inside VPC for Elasticsearch writes, connected via SQS.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Cost Analysis
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Monthly Cost (10 GB/month logs)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lambda (5-min polling)&lt;/td&gt;
&lt;td&gt;~$3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EventBridge Scheduler&lt;/td&gt;
&lt;td&gt;~$1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secrets Manager&lt;/td&gt;
&lt;td&gt;~$1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Elastic Cloud Serverless&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;~$95&lt;/strong&gt; (Standard tier)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Self-hosted (3× r6g.large)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;~$300&lt;/strong&gt; (EC2 + EBS)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Monthly Log Volume&lt;/th&gt;
&lt;th&gt;Elastic Cloud&lt;/th&gt;
&lt;th&gt;Self-Hosted&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1 GB&lt;/td&gt;
&lt;td&gt;Free trial&lt;/td&gt;
&lt;td&gt;EC2 cost only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10 GB&lt;/td&gt;
&lt;td&gt;~$95/month&lt;/td&gt;
&lt;td&gt;~$300/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100 GB&lt;/td&gt;
&lt;td&gt;~$500/month&lt;/td&gt;
&lt;td&gt;~$900/month&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Self-hosted has no per-GB ingestion cost but requires infrastructure management. Elastic Cloud Serverless eliminates ops burden at the cost of per-GB pricing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Gotchas &amp;amp; Lessons Learned
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Discovery&lt;/th&gt;
&lt;th&gt;Impact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;API Key must be in &lt;strong&gt;Encoded (Base64)&lt;/strong&gt; format, not the raw id:key pair&lt;/td&gt;
&lt;td&gt;Auth failures if stored incorrectly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Elastic Cloud Serverless returns data instantly (no indexing lag)&lt;/td&gt;
&lt;td&gt;Faster validation than some competitors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Daily indices (&lt;code&gt;fsxn-audit-YYYY.MM.DD&lt;/code&gt;) require ILM policy for cleanup&lt;/td&gt;
&lt;td&gt;Unbounded storage growth without ILM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;fsxn.path&lt;/code&gt; needs both &lt;code&gt;text&lt;/code&gt; and &lt;code&gt;keyword&lt;/code&gt; sub-field for full-text + exact match&lt;/td&gt;
&lt;td&gt;Missing queries if only one type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Bulk API recommended max ~10MB per request&lt;/td&gt;
&lt;td&gt;Lambda batches accordingly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;No built-in Firehose destination — Lambda direct delivery only&lt;/td&gt;
&lt;td&gt;Simpler architecture, but no Firehose buffering&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Data Sovereignty &amp;amp; Classification
&lt;/h2&gt;

&lt;p&gt;Audit logs contain fields classified as PII (&lt;code&gt;user.name&lt;/code&gt;) and sensitive business data (&lt;code&gt;fsxn.path&lt;/code&gt;). For data sovereignty deployments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Self-hosted&lt;/strong&gt;: Full control — implement field-level security in Elasticsearch to restrict PII access by role&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elastic Cloud&lt;/strong&gt;: Use Elastic's field-level security + ILM retention policies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redaction path&lt;/strong&gt;: Deploy OTel Collector (Part 5) with &lt;code&gt;attributes/redact&lt;/code&gt; processor before Elasticsearch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See the &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/data-classification.md" rel="noopener noreferrer"&gt;Data Classification Guide&lt;/a&gt; for field-by-field PII classification and recommended handling patterns per regulatory framework (APPI, GDPR, FISC, ISMAP).&lt;/p&gt;

&lt;h2&gt;
  
  
  Production Readiness
&lt;/h2&gt;

&lt;p&gt;This integration follows the project's &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations#production-readiness-levels--%E6%9C%AC%E7%95%AA%E6%BA%96%E5%82%99%E3%83%AC%E3%83%99%E3%83%AB" rel="noopener noreferrer"&gt;Production Readiness Levels&lt;/a&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;What You Get&lt;/th&gt;
&lt;th&gt;Go/No-Go to Next&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Level 1 (this Quick Start)&lt;/td&gt;
&lt;td&gt;Audit poller + DLQ&lt;/td&gt;
&lt;td&gt;Logs arrive, checkpoint advances, DLQ empty 24h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 2&lt;/td&gt;
&lt;td&gt;+ Kibana dashboard + alerts&lt;/td&gt;
&lt;td&gt;SLOs met 7 days, security review done&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 3&lt;/td&gt;
&lt;td&gt;+ DynamoDB ledger + poison-pill&lt;/td&gt;
&lt;td&gt;SLOs met 30 days, compliance pack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 4&lt;/td&gt;
&lt;td&gt;+ OTel Collector + redaction&lt;/td&gt;
&lt;td&gt;Multi-backend, PII redaction, DR tested&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Full criteria: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/pipeline-slo.md" rel="noopener noreferrer"&gt;Pipeline SLO Definitions&lt;/a&gt; | &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/runbooks/dlq-replay.md" rel="noopener noreferrer"&gt;DLQ Replay Runbook&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Enterprise scale&lt;/strong&gt;: For multi-account deployments, see the &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/multi-account-deployment.md" rel="noopener noreferrer"&gt;StackSets deployment guide&lt;/a&gt;. For DR, see &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/cross-region-replication.md" rel="noopener noreferrer"&gt;Cross-Region Replication&lt;/a&gt;. For compliance evidence collection, see the &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/compliance-evidence-pack.md" rel="noopener noreferrer"&gt;Compliance Evidence Pack&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  CloudFormation Templates
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Template&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Key Parameters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;template.yaml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;FSx audit log poller&lt;/td&gt;
&lt;td&gt;S3AccessPointArn, ElasticApiKeySecretArn, ElasticEndpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;template-ems.yaml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;EMS webhook handler&lt;/td&gt;
&lt;td&gt;ElasticApiKeySecretArn, ElasticEndpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;template-fpolicy.yaml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;FPolicy EventBridge handler&lt;/td&gt;
&lt;td&gt;ElasticApiKeySecretArn, ElasticEndpoint, EventBusName&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/tree/main/integrations/elastic" rel="noopener noreferrer"&gt;integrations/elastic/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elastic Cloud&lt;/strong&gt;: &lt;a href="https://cloud.elastic.co/" rel="noopener noreferrer"&gt;cloud.elastic.co&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elastic Common Schema&lt;/strong&gt;: &lt;a href="https://www.elastic.co/guide/en/ecs/current/index.html" rel="noopener noreferrer"&gt;ECS Reference&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kibana SIEM&lt;/strong&gt;: &lt;a href="https://www.elastic.co/guide/en/security/current/index.html" rel="noopener noreferrer"&gt;Security Solution&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Series GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/fsxn-observability-integrations&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Series Navigation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Part 1&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/why-your-fsx-for-ontap-audit-logs-deserve-better-than-ec2-kod"&gt;Why Your FSx for ONTAP Logs Deserve Better&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 2&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/shipping-fsx-for-ontap-logs-to-datadog-the-serverless-way-n9c"&gt;Shipping FSx for ONTAP Logs to Datadog — The Serverless Way&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 3&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/event-driven-ransomware-detection-with-ontap-arp-datadog-4cda"&gt;Event-Driven Ransomware Detection with ONTAP ARP + Datadog&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 4&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/fpolicy-file-activity-pipeline-ontap-to-datadog-via-ecs-fargate-2ing"&gt;FPolicy File Activity Pipeline — ONTAP to Datadog via ECS Fargate&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 5&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/escape-vendor-lock-in-multi-backend-log-delivery-with-otel-collector-for-fsx-for-ontap-2inb"&gt;Escape Vendor Lock-in: Multi-Backend Log Delivery with OTel Collector for FSx for ONTAP.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 6&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/direct-to-grafana-shipping-fsx-for-ontap-logs-to-grafana-cloud-loki-via-otlp-gateway-33hk"&gt;Direct-to-Grafana: Shipping FSx for ONTAP Logs to Grafana Cloud Loki via OTLP Gateway&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 7&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ship-fsx-for-ontap-audit-logs-to-new-relic-via-serverless-lambda-pipeline-3g87"&gt;Ship FSx for ONTAP Audit Logs to New Relic via Serverless Lambda Pipeline&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 8&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ec2-to-serverless-modernizing-fsx-for-ontap-splunk-integration-e8l"&gt;EC2 to Serverless: Modernizing FSx for ONTAP Splunk Integration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 9&lt;/strong&gt;: Data Sovereignty with Elastic (this post)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 10&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/high-cardinality-file-access-analysis-with-honeycomb-otel-1962"&gt;High-Cardinality File Access Analysis with Honeycomb + OTel&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 11&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ai-powered-root-cause-correlating-file-access-with-apm-via-dynatrace-4ffl"&gt;AI-Powered Root Cause: Correlating File Access with APM via Dynatrace&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 12&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/fsx-for-ontap-audit-logs-with-data-residency-in-your-region-46e6"&gt;FSx for ONTAP Audit Logs with Data Residency in your region with Sumo Logic&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 13&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/9-services-one-architecture-what-we-learned-shipping-fsx-for-ontap-logs-to-every-major-19ig"&gt;9 Vendors, One Architecture&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Questions about the Elastic integration or data sovereignty patterns? Drop a comment below.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/fsxn-observability-integrations&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>elastic</category>
      <category>observability</category>
      <category>amazonfsxfornetappontap</category>
    </item>
    <item>
      <title>EC2 to Serverless: Modernizing FSx for ONTAP Splunk Integration</title>
      <dc:creator>Yoshiki Fujiwara(藤原 善基)@AWS Community Builder</dc:creator>
      <pubDate>Sat, 30 May 2026 23:56:44 +0000</pubDate>
      <link>https://dev.to/aws-builders/ec2-to-serverless-modernizing-fsx-for-ontap-splunk-integration-e8l</link>
      <guid>https://dev.to/aws-builders/ec2-to-serverless-modernizing-fsx-for-ontap-splunk-integration-e8l</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://aws.amazon.com/jp/blogs/news/auditing-user-and-administrative-actions-on-amazon-fsx-for-netapp-ontap-using-splunk/" rel="noopener noreferrer"&gt;existing AWS Blog approach&lt;/a&gt; ships FSx for ONTAP audit logs to Splunk via &lt;strong&gt;two EC2 instances&lt;/strong&gt; (syslog-ng + Universal Forwarder). We replaced it with a single Lambda function — same Splunk index, same SPL queries, &lt;strong&gt;90% AWS infrastructure cost reduction&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Before] FSx for ONTAP → syslog-ng (EC2) → Splunk UF (EC2) → Splunk
         Monthly AWS infra cost: ~$66 (2× t3.medium + EBS)
         Ops burden: OS patching, agent updates, scaling

[After]  FSx for ONTAP → S3 Access Point → Lambda → Splunk HEC
         Monthly AWS infra cost: ~$6 (Lambda + EventBridge)
         Ops burden: Zero (managed services only)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: The 90% cost reduction refers to &lt;strong&gt;AWS infrastructure costs only&lt;/strong&gt; (EC2/Lambda/EventBridge). Splunk platform licensing costs remain unchanged regardless of the delivery method.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is Part 8 of the &lt;a href="https://dev.to/aws-builders/why-your-fsx-for-ontap-audit-logs-deserve-better-than-ec2-kod"&gt;Serverless Observability for FSx for ONTAP&lt;/a&gt; series.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem with EC2-Based Splunk Integration
&lt;/h2&gt;

&lt;p&gt;The AWS Blog's architecture works, but it comes with operational overhead:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concern&lt;/th&gt;
&lt;th&gt;EC2-Based&lt;/th&gt;
&lt;th&gt;Serverless&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Monthly cost&lt;/td&gt;
&lt;td&gt;~$66 fixed&lt;/td&gt;
&lt;td&gt;~$6 pay-per-use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OS patching&lt;/td&gt;
&lt;td&gt;Monthly&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent updates&lt;/td&gt;
&lt;td&gt;Manual (UF + syslog-ng)&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaling&lt;/td&gt;
&lt;td&gt;Manual instance resize&lt;/td&gt;
&lt;td&gt;Automatic (Lambda concurrency)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Availability&lt;/td&gt;
&lt;td&gt;Single AZ (unless you add redundancy)&lt;/td&gt;
&lt;td&gt;Multi-AZ by default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time to deploy&lt;/td&gt;
&lt;td&gt;Hours (provision + configure)&lt;/td&gt;
&lt;td&gt;30 minutes (CloudFormation)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you're already running this EC2 pattern and want to modernize, this article shows you how — with a parallel deployment strategy that ensures zero data loss during cutover.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────────────────┐
│ FSx for ONTAP                                            │
│                                                          │
│  Audit Volume ──→ S3 Access Point                        │
│                        │                                 │
│                        ▼                                 │
│  EventBridge Scheduler (rate: 5 min)                     │
│                        │                                 │
│                        ▼                                 │
│  Lambda (Python 3.12)                                    │
│    • Reads audit logs via S3 AP                          │
│    • Parses JSON/EVTX                                    │
│    • Formats as Splunk HEC events                        │
│    • Sends with Authorization: Splunk &amp;lt;token&amp;gt;            │
│    • Checkpoints in SSM Parameter Store                  │
│                        │                                 │
│                        ▼                                 │
│  Splunk HEC                                              │
│  https://&amp;lt;splunk&amp;gt;:8088/services/collector/event          │
│  Response: {"text":"Success","code":0}                   │
│                                                          │
│  SPL: index=fsxn_audit sourcetype=fsxn:ontap:audit       │
└──────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  High-Volume Alternative: Firehose Path
&lt;/h3&gt;

&lt;p&gt;For sustained &amp;gt;1000 events/sec, use Kinesis Data Firehose with its built-in Splunk destination:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FSx for ONTAP → S3 AP → Lambda (transform) → Kinesis Data Firehose → Splunk HEC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A separate &lt;code&gt;template-firehose.yaml&lt;/code&gt; is provided for this path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migration Strategy (Zero Data Loss)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Phase 1: Parallel Deployment (Day 1-3)
&lt;/h3&gt;

&lt;p&gt;Deploy the serverless stack alongside the existing EC2 pipeline. Use a &lt;strong&gt;separate Splunk index&lt;/strong&gt; for validation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudformation deploy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--template-file&lt;/span&gt; integrations/splunk-serverless/template.yaml &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--stack-name&lt;/span&gt; fsxn-splunk-integration &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--parameter-overrides&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;S3AccessPointArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;S3_AP_ARN&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;SplunkHecTokenSecretArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;SECRET_ARN&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;SplunkHecEndpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://splunk.example.com:8088 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;S3BucketName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;BUCKET&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;SplunkIndex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;fsxn_audit_serverless &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--capabilities&lt;/span&gt; CAPABILITY_IAM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare events between old and new pipelines for 48 hours:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| stats count by index
| where index IN ("fsxn_audit", "fsxn_audit_serverless")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Phase 2: Cutover (Day 4-5)
&lt;/h3&gt;

&lt;p&gt;Once event parity is confirmed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Update the stack to use the production index (&lt;code&gt;fsxn_audit&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Stop the syslog-ng and UF services on EC2 (don't terminate yet)&lt;/li&gt;
&lt;li&gt;Monitor for 24 hours&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Phase 3: Cleanup (Day 7+)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Terminate EC2 instances&lt;/span&gt;
&lt;span class="c"&gt;# Remove security groups, IAM roles, EBS volumes&lt;/span&gt;
&lt;span class="c"&gt;# Delete old CloudFormation/Terraform resources&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What Changes for Splunk Users
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Unchanged ✅
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Index name and sourcetype (configurable)&lt;/li&gt;
&lt;li&gt;SPL queries — same field names&lt;/li&gt;
&lt;li&gt;Dashboards and saved searches&lt;/li&gt;
&lt;li&gt;Alert rules&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Changed ⚠️
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;host&lt;/code&gt; field: EC2 hostname → SVM name&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;source&lt;/code&gt; field: syslog path → &lt;code&gt;fsxn-observability&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Delivery latency: near-real-time (syslog) → polling interval (default 5 min)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  HEC Event Format
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1716508800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"svm-prod-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fsxn-observability"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sourcetype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fsxn:ontap:audit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fsxn_audit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"event_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4663"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"admin@corp.local"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"operation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ReadData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/vol/data/report.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"client_ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"10.0.1.50"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  SPL Query Examples
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Failed access attempts
index=fsxn_audit sourcetype=fsxn:ontap:audit result=Failure
| stats count by user, path
| sort -count

# Operations timeline
index=fsxn_audit sourcetype=fsxn:ontap:audit
| timechart span=5m count by operation

# Top users
index=fsxn_audit sourcetype=fsxn:ontap:audit
| stats count by user
| sort -count
| head 20

# Specific user investigation
index=fsxn_audit sourcetype=fsxn:ontap:audit user="admin@corp.local"
| table _time, operation, path, result, client_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cost Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;EC2-Based (monthly)&lt;/th&gt;
&lt;th&gt;Serverless (monthly)&lt;/th&gt;
&lt;th&gt;Savings&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;EC2 instances (2× t3.medium)&lt;/td&gt;
&lt;td&gt;$60&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EBS volumes (2× 20GB)&lt;/td&gt;
&lt;td&gt;$6&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lambda&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;~$5&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EventBridge Scheduler&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;~$0.01&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secrets Manager&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;~$0.40&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$66&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;91%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: EC2 cost assumes 2× t3.medium (as per the &lt;a href="https://aws.amazon.com/jp/blogs/news/auditing-user-and-administrative-actions-on-amazon-fsx-for-netapp-ontap-using-splunk/" rel="noopener noreferrer"&gt;AWS Blog reference architecture&lt;/a&gt;). Actual EC2 costs vary by instance type and region. Splunk Cloud licensing costs are contract-dependent and may differ significantly from list pricing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Network Considerations
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Splunk Deployment&lt;/th&gt;
&lt;th&gt;Lambda Config&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Splunk Cloud (public HEC)&lt;/td&gt;
&lt;td&gt;Lambda outside VPC&lt;/td&gt;
&lt;td&gt;Simplest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Splunk Enterprise (private VPC)&lt;/td&gt;
&lt;td&gt;Lambda in VPC + NAT&lt;/td&gt;
&lt;td&gt;Same VPC as Splunk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Splunk Cloud (PrivateLink)&lt;/td&gt;
&lt;td&gt;Lambda in VPC + VPC Endpoint&lt;/td&gt;
&lt;td&gt;Most secure&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;VerifySSL&lt;/strong&gt;: Set to &lt;code&gt;true&lt;/code&gt; in production. Only use &lt;code&gt;false&lt;/code&gt; for self-signed certs in dev environments.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Rollback Plan
&lt;/h2&gt;

&lt;p&gt;If issues are discovered after cutover:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start the stopped EC2 instances (syslog-ng + UF)&lt;/li&gt;
&lt;li&gt;Verify syslog-ng is receiving events&lt;/li&gt;
&lt;li&gt;Delete the serverless CloudFormation stack&lt;/li&gt;
&lt;li&gt;Investigate and resolve before re-attempting&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The serverless Lambda uses checkpointing — no events are lost during the overlap period (brief duplicates are possible).&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Firehose path&lt;/strong&gt;: For high-volume logs (&amp;gt;1000 events/sec), use &lt;code&gt;template-firehose.yaml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HEC Acknowledgment (&lt;code&gt;useACK&lt;/code&gt;)&lt;/strong&gt;: For Level 2+, enable HEC indexer acknowledgment to guarantee at-least-once delivery. Lambda waits for ack before advancing checkpoint&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIM compliance&lt;/strong&gt;: Map fields to Splunk's &lt;a href="https://docs.splunk.com/Documentation/CIM/latest/User/Overview" rel="noopener noreferrer"&gt;Common Information Model&lt;/a&gt; (&lt;code&gt;Authentication&lt;/code&gt; or &lt;code&gt;Change&lt;/code&gt; data model) for compatibility with Splunk Enterprise Security correlation searches&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Index pre-creation&lt;/strong&gt;: The &lt;code&gt;fsxn_audit&lt;/code&gt; index must be created before first ingestion (Splunk Cloud: Admin Console; Enterprise: &lt;code&gt;indexes.conf&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EMS webhooks&lt;/strong&gt;: Real-time ARP ransomware detection alerts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FPolicy&lt;/strong&gt;: Sub-second file operation streaming&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production Readiness&lt;/strong&gt;: Progress from Level 1 (this Quick Start) to Level 4 (Enterprise) — see the &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/pipeline-slo.md" rel="noopener noreferrer"&gt;Pipeline SLO Definitions&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Production Readiness
&lt;/h2&gt;

&lt;p&gt;This integration follows the project's &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations#production-readiness-levels--%E6%9C%AC%E7%95%AA%E6%BA%96%E5%82%99%E3%83%AC%E3%83%99%E3%83%AB" rel="noopener noreferrer"&gt;Production Readiness Levels&lt;/a&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;What You Get&lt;/th&gt;
&lt;th&gt;Go/No-Go to Next&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Level 1 (this Quick Start)&lt;/td&gt;
&lt;td&gt;Audit poller + DLQ&lt;/td&gt;
&lt;td&gt;Logs arrive, checkpoint advances, DLQ empty 24h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 2&lt;/td&gt;
&lt;td&gt;+ Splunk dashboards + alerts&lt;/td&gt;
&lt;td&gt;SLOs met 7 days, security review done&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 3&lt;/td&gt;
&lt;td&gt;+ DynamoDB ledger + poison-pill&lt;/td&gt;
&lt;td&gt;SLOs met 30 days, compliance pack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 4&lt;/td&gt;
&lt;td&gt;+ OTel Collector + redaction&lt;/td&gt;
&lt;td&gt;Multi-backend, PII redaction, DR tested&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Data classification&lt;/strong&gt;: Splunk receives &lt;code&gt;user&lt;/code&gt; and &lt;code&gt;path&lt;/code&gt; fields (PII/sensitive). For Splunk Cloud, data is processed in the vendor's infrastructure. For self-hosted Splunk Enterprise, data stays in your VPC. See &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/data-classification.md" rel="noopener noreferrer"&gt;Data Classification Guide&lt;/a&gt; for field-by-field PII classification and handling patterns.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Full criteria: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/pipeline-slo.md" rel="noopener noreferrer"&gt;Pipeline SLO Definitions&lt;/a&gt; | &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/runbooks/dlq-replay.md" rel="noopener noreferrer"&gt;DLQ Replay Runbook&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/tree/main/integrations/splunk-serverless" rel="noopener noreferrer"&gt;GitHub: fsxn-observability-integrations/integrations/splunk-serverless&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/integrations/splunk-serverless/docs/en/migration-from-ec2.md" rel="noopener noreferrer"&gt;Migration Guide (detailed)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/jp/blogs/news/auditing-user-and-administrative-actions-on-amazon-fsx-for-netapp-ontap-using-splunk/" rel="noopener noreferrer"&gt;AWS Blog: EC2-based approach&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.splunk.com/Documentation/Splunk/latest/Data/FormateventsforHTTPEventCollector" rel="noopener noreferrer"&gt;Splunk HEC Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/pipeline-slo.md" rel="noopener noreferrer"&gt;Pipeline SLO Definitions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/data-classification.md" rel="noopener noreferrer"&gt;Data Classification Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Series Navigation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Part 1&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/why-your-fsx-for-ontap-audit-logs-deserve-better-than-ec2-kod"&gt;Why Your FSx for ONTAP Audit Logs Deserve Better Than EC2&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 2&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/shipping-fsx-for-ontap-logs-to-datadog-the-serverless-way-n9c"&gt;Shipping FSx for ONTAP Logs to Datadog — The Serverless Way&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 3&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/event-driven-ransomware-detection-with-ontap-arp-datadog-4cda"&gt;Event-Driven Ransomware Detection with ONTAP ARP + Datadog&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 4&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/fpolicy-file-activity-pipeline-ontap-to-datadog-via-ecs-fargate-2ing"&gt;FPolicy File Activity Pipeline — ONTAP to Datadog via ECS Fargate&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 5&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/escape-vendor-lock-in-multi-backend-log-delivery-with-otel-collector-for-fsx-for-ontap-2inb"&gt;Escape Vendor Lock-in: Multi-Backend Log Delivery with OTel Collector for FSx for ONTAP.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 6&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/direct-to-grafana-shipping-fsx-for-ontap-logs-to-grafana-cloud-loki-via-otlp-gateway-33hk"&gt;Direct-to-Grafana: Shipping FSx for ONTAP Logs to Grafana Cloud Loki via OTLP Gateway&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 7&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ship-fsx-for-ontap-audit-logs-to-new-relic-via-serverless-lambda-pipeline-3g87"&gt;Ship FSx for ONTAP Audit Logs to New Relic via Serverless Lambda Pipeline&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 8&lt;/strong&gt;: EC2 to Serverless: Modernizing Splunk Integration (this post)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 9&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/data-sovereignty-fsx-for-ontap-logs-in-your-vpc-with-elastic-1mog"&gt;Data Sovereignty: FSx for ONTAP Logs in Your VPC with Elastic&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 10&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/high-cardinality-file-access-analysis-with-honeycomb-otel-1962"&gt;High-Cardinality File Access Analysis with Honeycomb + OTel&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 11&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ai-powered-root-cause-correlating-file-access-with-apm-via-dynatrace-4ffl"&gt;AI-Powered Root Cause: Correlating File Access with APM via Dynatrace&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 12&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/fsx-for-ontap-audit-logs-with-data-residency-in-your-region-46e6"&gt;FSx for ONTAP Audit Logs with Data Residency in your region with Sumo Logic&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 13&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/9-services-one-architecture-what-we-learned-shipping-fsx-for-ontap-logs-to-every-major-19ig"&gt;9 Vendors, One Architecture&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Questions about the Splunk migration or serverless HEC delivery? Drop a comment below.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/fsxn-observability-integrations&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>splunk</category>
      <category>observability</category>
      <category>amazonfsxfornetappontap</category>
    </item>
    <item>
      <title>Ship FSx for ONTAP Audit Logs to New Relic via Serverless Lambda Pipeline</title>
      <dc:creator>Yoshiki Fujiwara(藤原 善基)@AWS Community Builder</dc:creator>
      <pubDate>Sat, 30 May 2026 23:38:34 +0000</pubDate>
      <link>https://dev.to/aws-builders/ship-fsx-for-ontap-audit-logs-to-new-relic-via-serverless-lambda-pipeline-3g87</link>
      <guid>https://dev.to/aws-builders/ship-fsx-for-ontap-audit-logs-to-new-relic-via-serverless-lambda-pipeline-3g87</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;New Relic's &lt;strong&gt;100 GB/month free tier&lt;/strong&gt; makes it the lowest-barrier entry point for FSx for ONTAP audit log observability. Deploy a single CloudFormation stack, and your file access events are queryable in NRQL within 30 minutes — no credit card required.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FSx for ONTAP audit volume
  → S3 Access Point
    → EventBridge Scheduler (every 5 min)
      → Lambda (reads + formats)
        → New Relic Log API v1 (HTTP 202)
          → NRQL queryable in ~30 seconds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is Part 7 of the &lt;a href="https://dev.to/aws-builders/why-your-fsx-for-ontap-audit-logs-deserve-better-than-ec2-kod"&gt;Serverless Observability for FSx for ONTAP&lt;/a&gt; series. Previous parts covered &lt;a href="https://dev.to/aws-builders/shipping-fsx-for-ontap-logs-to-datadog-the-serverless-way-n9c"&gt;Datadog&lt;/a&gt;, &lt;a href="https://dev.to/aws-builders/escape-vendor-lock-in-multi-backend-log-delivery-with-otel-collector-for-fsx-for-ontap-2inb"&gt;OTel Collector&lt;/a&gt;, and &lt;a href="https://dev.to/aws-builders/direct-to-grafana-shipping-fsx-for-ontap-logs-to-grafana-cloud-loki-via-otlp-gateway-33hk"&gt;Grafana Cloud&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why New Relic for FSx for ONTAP Audit Logs?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criteria&lt;/th&gt;
&lt;th&gt;New Relic&lt;/th&gt;
&lt;th&gt;Comparison&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Free tier&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;100 GB/month&lt;/strong&gt; (permanent, no expiry)&lt;/td&gt;
&lt;td&gt;Grafana: 50 GB/month (14-day retention), Sumo Logic: 500 MB/day (~15 GB/month), Datadog: none&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retention (free)&lt;/td&gt;
&lt;td&gt;30 days&lt;/td&gt;
&lt;td&gt;Grafana: 14 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Query language&lt;/td&gt;
&lt;td&gt;NRQL (SQL-like)&lt;/td&gt;
&lt;td&gt;Familiar to anyone who knows SQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alert conditions&lt;/td&gt;
&lt;td&gt;NRQL-based, free&lt;/td&gt;
&lt;td&gt;Included in free tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Credit card required&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Some vendors require CC for trial&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For a typical FSx for ONTAP file server generating 1-10 GB/month of audit logs, &lt;strong&gt;New Relic's free tier covers the entire workload at zero cost&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────────────────┐
│ FSx for ONTAP                                            │
│                                                          │
│  Audit Volume ──→ S3 Access Point                        │
│                        │                                 │
│                        ▼                                 │
│  EventBridge Scheduler (rate: 5 min)                     │
│                        │                                 │
│                        ▼                                 │
│  Lambda (Python 3.12)                                    │
│    • Reads audit logs via S3 AP                          │
│    • Parses JSON/EVTX                                    │
│    • Formats for New Relic Log API                       │
│    • Sends gzip-compressed payload                       │
│    • Checkpoints in SSM Parameter Store                  │
│                        │                                 │
│                        ▼                                 │
│  New Relic Log API v1                                    │
│  https://log-api.newrelic.com/log/v1                     │
│  Header: Api-Key: &amp;lt;license-key&amp;gt;                          │
│  Response: HTTP 202 + requestId                          │
│                                                          │
│                        ▼                                 │
│  NRQL: SELECT * FROM Log WHERE source='fsxn-ontap'       │
└──────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Quick Start (30 Minutes)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;AWS account with FSx for ONTAP + S3 Access Point configured (see &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/prerequisites.md" rel="noopener noreferrer"&gt;Prerequisites Guide&lt;/a&gt; if not yet set up — allow 1-2 hours for initial FSx for ONTAP + S3 AP configuration)&lt;/li&gt;
&lt;li&gt;New Relic free account (&lt;a href="https://newrelic.com/signup" rel="noopener noreferrer"&gt;sign up here&lt;/a&gt; — no credit card)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Get Your License Key
&lt;/h3&gt;

&lt;p&gt;New Relic removed the "Copy key" button from the UI in September 2024. Use the NerdGraph API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Create a User API Key in New Relic UI (API Keys page)&lt;/span&gt;
&lt;span class="c"&gt;# 2. Store it in an environment variable (never pass keys inline):&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;NR_USER_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"NRAK-YOUR-USER-KEY"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;NR_ACCOUNT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"YOUR_ACCOUNT_ID"&lt;/span&gt;

&lt;span class="c"&gt;# 3. Use it to query the License Key via NerdGraph:&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.newrelic.com/graphql"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"API-Key: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NR_USER_API_KEY&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;query&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;{ actor { apiAccess { keySearch(query: {types: INGEST, scope: {accountIds: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NR_ACCOUNT_ID&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;}}) { keys { ... on ApiAccessIngestKey { key name type } } } } } }&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.data.actor.apiAccess.keySearch.keys[0].key'&lt;/span&gt;

&lt;span class="c"&gt;# The output is your License Key — store it securely, do not log it.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Store in Secrets Manager
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws secretsmanager create-secret &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"new-relic/fsxn-license-key"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--secret-string&lt;/span&gt; &lt;span class="s1"&gt;'{"license_key":"YOUR_LICENSE_KEY_HERE"}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; ap-northeast-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;For automated credential rotation, see the &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/shared/templates/secrets-rotation-sample.yaml" rel="noopener noreferrer"&gt;Secrets Rotation Sample Template&lt;/a&gt; which provides a Lambda-based rotation pattern for all vendor integrations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 3: Deploy
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudformation deploy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--template-file&lt;/span&gt; integrations/new-relic/template.yaml &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--stack-name&lt;/span&gt; fsxn-new-relic-integration &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--parameter-overrides&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;S3AccessPointArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arn:aws:s3:ap-northeast-1:123456789012:accesspoint/fsxn-audit &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;NewRelicLicenseKeySecretArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;SECRET_ARN&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;NewRelicRegion&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;US &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;S3BucketName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;YOUR_BUCKET&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--capabilities&lt;/span&gt; CAPABILITY_NAMED_IAM &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; ap-northeast-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Verify
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- In New Relic Query Builder:&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Log&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'fsxn-ontap'&lt;/span&gt; &lt;span class="n"&gt;SINCE&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="n"&gt;minutes&lt;/span&gt; &lt;span class="n"&gt;ago&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see results, you're done. The pipeline is working.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Gets Shipped
&lt;/h2&gt;

&lt;p&gt;Each audit log event is formatted as a New Relic log entry with structured attributes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;EventID&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;4663&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;UserName&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;admin@corp.local&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,...}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1716508800000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"attributes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fsxn-ontap"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ontap-audit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"event_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4663"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"svm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"svm-prod-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"admin@corp.local"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"client_ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"10.0.1.50"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"operation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ReadData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/vol/data/report.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"s3_key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"audit/svm-prod-01/2026/05/24/audit-001.json"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: New Relic requires &lt;code&gt;timestamp&lt;/code&gt; as Unix epoch in &lt;strong&gt;milliseconds&lt;/strong&gt; (not seconds, not ISO 8601 strings). Our Lambda handles this conversion automatically.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  NRQL Query Examples
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Failed access attempts (security investigation)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Log&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'fsxn-ontap'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Failure'&lt;/span&gt;
&lt;span class="n"&gt;FACET&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;
&lt;span class="n"&gt;SINCE&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;hour&lt;/span&gt; &lt;span class="n"&gt;ago&lt;/span&gt;

&lt;span class="c1"&gt;-- Top users by file access volume&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Log&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'fsxn-ontap'&lt;/span&gt;
&lt;span class="n"&gt;FACET&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;
&lt;span class="n"&gt;SINCE&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;day&lt;/span&gt; &lt;span class="n"&gt;ago&lt;/span&gt;

&lt;span class="c1"&gt;-- Operations breakdown (pie chart)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Log&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'fsxn-ontap'&lt;/span&gt;
&lt;span class="n"&gt;FACET&lt;/span&gt; &lt;span class="k"&gt;operation&lt;/span&gt;
&lt;span class="n"&gt;SINCE&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;hour&lt;/span&gt; &lt;span class="n"&gt;ago&lt;/span&gt;

&lt;span class="c1"&gt;-- Time series for anomaly detection&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Log&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'fsxn-ontap'&lt;/span&gt;
&lt;span class="n"&gt;TIMESERIES&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="n"&gt;minutes&lt;/span&gt;
&lt;span class="n"&gt;SINCE&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="n"&gt;hours&lt;/span&gt; &lt;span class="n"&gt;ago&lt;/span&gt;

&lt;span class="c1"&gt;-- Specific user investigation&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Log&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'fsxn-ontap'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'admin@corp.local'&lt;/span&gt;
&lt;span class="n"&gt;SINCE&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;hour&lt;/span&gt; &lt;span class="n"&gt;ago&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Alert Configuration
&lt;/h2&gt;

&lt;p&gt;Create a NRQL alert condition to detect failed access spikes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;alertsNrqlConditionStaticCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;YOUR_ACCOUNT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;policyId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;YOUR_POLICY_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"FSxN Failed Access Spike"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;nrql&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SELECT count(*) FROM Log WHERE source = 'fsxn-ontap' AND result = 'Failure'"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;terms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;thresholdOccurrences&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AT_LEAST_ONCE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;thresholdDuration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ABOVE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CRITICAL&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This fires when more than 10 failed access attempts occur in a 5-minute window.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Threshold rationale&lt;/strong&gt;: In typical FSx for ONTAP environments, failed access attempts are 0-2 per 5-minute window during normal operations (e.g., stale NFS handles, permission misconfigurations). A threshold of 10 indicates a potential brute-force attempt or systematic misconfiguration. Adjust based on your baseline — monitor for 1 week before setting production thresholds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Cost Analysis
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Monthly Log Volume&lt;/th&gt;
&lt;th&gt;AWS Cost&lt;/th&gt;
&lt;th&gt;New Relic Cost&lt;/th&gt;
&lt;th&gt;Total&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1 GB&lt;/td&gt;
&lt;td&gt;~$2&lt;/td&gt;
&lt;td&gt;$0 (free tier)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$2&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10 GB&lt;/td&gt;
&lt;td&gt;~$8&lt;/td&gt;
&lt;td&gt;$0 (free tier)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$8&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50 GB&lt;/td&gt;
&lt;td&gt;~$25&lt;/td&gt;
&lt;td&gt;$0 (free tier)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$25&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100 GB&lt;/td&gt;
&lt;td&gt;~$41&lt;/td&gt;
&lt;td&gt;$0 (at limit)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$41&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200 GB&lt;/td&gt;
&lt;td&gt;~$80&lt;/td&gt;
&lt;td&gt;$35 (overage)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$115&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;For comparison, the EC2-based approach (syslog-ng + Universal Forwarder) costs ~$66/month in fixed infrastructure regardless of log volume.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Gotchas We Discovered
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. License Key Retrieval (Post-September 2024)
&lt;/h3&gt;

&lt;p&gt;New Relic removed the "Copy key" button from the API Keys UI. You must use NerdGraph to retrieve the full License Key value using the Key ID.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Timestamp Format
&lt;/h3&gt;

&lt;p&gt;New Relic's Log API rejects ISO 8601 strings with &lt;code&gt;Error unmarshalling message payload&lt;/code&gt;. Timestamps must be Unix epoch in &lt;strong&gt;milliseconds&lt;/strong&gt; (integer).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Wrong: "2026-01-15T12:00:00Z" → rejected
# Right: 1768478400000 → accepted
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. New Account Initialization Lag
&lt;/h3&gt;

&lt;p&gt;First-time data ingestion on a new account may take 5-10 minutes to appear in the UI. Subsequent deliveries appear within 30 seconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. US vs EU Region
&lt;/h3&gt;

&lt;p&gt;Choose your region at signup. It cannot be changed later. For Japan-based workloads, US is recommended until the &lt;a href="https://www.businesswire.com/news/home/20260311313901/en" rel="noopener noreferrer"&gt;Tokyo data center launches in July 2026&lt;/a&gt; (announced March 2026).&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;EMS webhooks&lt;/strong&gt;: Receive ONTAP system events (ARP ransomware detection, quota alerts) in real-time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FPolicy events&lt;/strong&gt;: Stream file operations with sub-second latency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OTel Collector path&lt;/strong&gt;: If you later need multi-backend delivery, the same log format works with the &lt;a href="https://dev.to/aws-builders/escape-vendor-lock-in-multi-backend-log-delivery-with-otel-collector-for-fsx-for-ontap-2inb"&gt;Part 5 Collector&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OTLP ingest&lt;/strong&gt;: New Relic supports OTLP natively — if you adopt OTel Collector, you can switch from Log API v1 to OTLP without changing the Lambda code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;logtype&lt;/code&gt; attribute&lt;/strong&gt;: Add &lt;code&gt;"logtype": "fsxn-ontap-audit"&lt;/code&gt; to enable New Relic's automatic Parsing Rules for structured field extraction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production Readiness&lt;/strong&gt;: Progress from Level 1 (this Quick Start) to Level 4 (Enterprise) — see the &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/pipeline-slo.md" rel="noopener noreferrer"&gt;Pipeline SLO Definitions&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Production Readiness
&lt;/h2&gt;

&lt;p&gt;This integration follows the project's &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations#production-readiness-levels--%E6%9C%AC%E7%95%AA%E6%BA%96%E5%82%99%E3%83%AC%E3%83%99%E3%83%AB" rel="noopener noreferrer"&gt;Production Readiness Levels&lt;/a&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;What You Get&lt;/th&gt;
&lt;th&gt;Go/No-Go to Next&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Level 1 (this Quick Start)&lt;/td&gt;
&lt;td&gt;Audit poller + DLQ&lt;/td&gt;
&lt;td&gt;Logs arrive, checkpoint advances, DLQ empty 24h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 2&lt;/td&gt;
&lt;td&gt;+ NRQL dashboards + alerts&lt;/td&gt;
&lt;td&gt;SLOs met 7 days, security review done&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 3&lt;/td&gt;
&lt;td&gt;+ DynamoDB ledger + poison-pill&lt;/td&gt;
&lt;td&gt;SLOs met 30 days, compliance pack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level 4&lt;/td&gt;
&lt;td&gt;+ OTel Collector + redaction&lt;/td&gt;
&lt;td&gt;Multi-backend, PII redaction, DR tested&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Data classification&lt;/strong&gt;: New Relic receives &lt;code&gt;user&lt;/code&gt; and &lt;code&gt;path&lt;/code&gt; fields (PII/sensitive). New Relic currently processes data in US and EU regions. For Japan-based workloads requiring data residency, evaluate cross-border transfer requirements with your compliance team. See &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/data-classification.md" rel="noopener noreferrer"&gt;Data Classification Guide&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Full criteria: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/pipeline-slo.md" rel="noopener noreferrer"&gt;Pipeline SLO Definitions&lt;/a&gt; | &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/runbooks/dlq-replay.md" rel="noopener noreferrer"&gt;DLQ Replay Runbook&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note on S3 AP network path&lt;/strong&gt;: The Lambda in this integration is deployed &lt;strong&gt;outside VPC&lt;/strong&gt; (no VPC configuration) for simplest S3 Access Point access. If your Lambda needs VPC access for other reasons, add a NAT Gateway — see the &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/s3ap-fsxn-specification.md" rel="noopener noreferrer"&gt;S3 AP Specification&lt;/a&gt; for network constraints.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/tree/main/integrations/new-relic" rel="noopener noreferrer"&gt;GitHub: fsxn-observability-integrations/integrations/new-relic&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.newrelic.com/docs/logs/log-api/introduction-log-api/" rel="noopener noreferrer"&gt;New Relic Log API Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://newrelic.com/pricing" rel="noopener noreferrer"&gt;New Relic Free Tier Details&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/pipeline-slo.md" rel="noopener noreferrer"&gt;Pipeline SLO Definitions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations/blob/main/docs/en/data-classification.md" rel="noopener noreferrer"&gt;Data Classification Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Series Navigation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Part 1&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/why-your-fsx-for-ontap-audit-logs-deserve-better-than-ec2-kod"&gt;Why Your FSx for ONTAP Audit Logs Deserve Better Than EC2&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 2&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/shipping-fsx-for-ontap-logs-to-datadog-the-serverless-way-n9c"&gt;Shipping FSx for ONTAP Logs to Datadog — The Serverless Way&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 3&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/event-driven-ransomware-detection-with-ontap-arp-datadog-4cda"&gt;Event-Driven Ransomware Detection with ONTAP ARP + Datadog&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 4&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/fpolicy-file-activity-pipeline-ontap-to-datadog-via-ecs-fargate-2ing"&gt;FPolicy File Activity Pipeline — ONTAP to Datadog via ECS Fargate&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 5&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/escape-vendor-lock-in-multi-backend-log-delivery-with-otel-collector-for-fsx-for-ontap-2inb"&gt;Escape Vendor Lock-in: Multi-Backend Log Delivery with OTel Collector for FSx for ONTAP.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 6&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/direct-to-grafana-shipping-fsx-for-ontap-logs-to-grafana-cloud-loki-via-otlp-gateway-33hk"&gt;Direct-to-Grafana: Shipping FSx for ONTAP Logs to Grafana Cloud Loki via OTLP Gateway&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 7&lt;/strong&gt;: Ship FSx for ONTAP Audit Logs to New Relic via Serverless Lambda Pipeline (this post)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 8&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ec2-to-serverless-modernizing-fsx-for-ontap-splunk-integration-e8l"&gt;EC2 to Serverless: Modernizing FSx for ONTAP Splunk Integration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 9&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/data-sovereignty-fsx-for-ontap-logs-in-your-vpc-with-elastic-1mog"&gt;Data Sovereignty: FSx for ONTAP Logs in Your VPC with Elastic&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 10&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/high-cardinality-file-access-analysis-with-honeycomb-otel-1962"&gt;High-Cardinality File Access Analysis with Honeycomb + OTel&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 11&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/ai-powered-root-cause-correlating-file-access-with-apm-via-dynatrace-4ffl"&gt;AI-Powered Root Cause: Correlating File Access with APM via Dynatrace&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 12&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/fsx-for-ontap-audit-logs-with-data-residency-in-your-region-46e6"&gt;FSx for ONTAP Audit Logs with Data Residency in your region with Sumo Logic&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 13&lt;/strong&gt;: &lt;a href="https://dev.to/aws-builders/9-services-one-architecture-what-we-learned-shipping-fsx-for-ontap-logs-to-every-major-19ig"&gt;9 Vendors, One Architecture&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Questions about the New Relic integration or the 100GB free tier? Drop a comment below.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Yoshiki0705/fsxn-observability-integrations" rel="noopener noreferrer"&gt;github.com/Yoshiki0705/fsxn-observability-integrations&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>newrelic</category>
      <category>observability</category>
      <category>amazonfsxfornetappontap</category>
    </item>
  </channel>
</rss>
