new glimpse approach

This commit is contained in:
2026-05-27 10:12:45 -07:00
parent 6e65df2591
commit 2b9648dd1a
9 changed files with 768 additions and 23 deletions

View File

@@ -0,0 +1 @@
{"ID":"842a4264-8857-6f39-d95a-cbc58d58337d","Operation":"OperationTypePlan","Info":"","Who":"noti@pop-os","Version":"1.15.1","Created":"2026-05-27T17:06:58.450709065Z","Path":"terraform.tfstate"}

View File

@@ -2,7 +2,6 @@
import base64
import json
import os
import re
import urllib.request
from dotenv import load_dotenv
@@ -24,29 +23,81 @@ def slurp_file(filename):
return file.read()
BASE_PROMPT="""You are an invoice extraction assistant. Your job is to read PDF documents and extract all invoice and credit note details into structured JSON.
BASE_PROMPT="""You are an invoice extraction assistant. Your job is to read PDF documents and extract all invoice and credit note details.
DOCUMENT TYPES YOU MAY ENCOUNTER:
1. **Single Invoice** — one invoice with line items, totals, dates, etc.
2. **Credit Note** — similar to an invoice but represents a credit/refund. Extract it the same way; the total will be positive (the credit amount).
3. **Statement / Summary** — a document listing multiple invoices or credits in a table or list format. Each row or entry represents a separate invoice/credit. Extract EACH one as a separate object in the output array.
3. **Statement / Summary** — a document listing multiple invoices or credits in a table or list format. Each row or entry represents a separate invoice/credit.
4. **Mixed** — a document containing both invoices and credits.
EXTRACTION RULES:
- Extract EVERY invoice or credit you can find. If the document is a statement listing 10 invoices, return all 10.
- Extract EVERY invoice or credit you can find. If the document is a statement listing 10 invoices, include all 10 in the invoices array.
- **customer_identifier**: The name of the customer/buyer. Look for "Bill To", "Customer", "Sold To", or the company name at the top.
- **vendor_identifier**: The name of the vendor/seller. Look for "From", "Vendor", "Supplier", letterhead, or the company issuing the document.
- **date**: The invoice date in ISO 8601 format (YYYY-MM-DD). If multiple dates exist, use the invoice date, not the due date or statement period.
- **invoice_number**: The unique invoice or credit note number. Look for labels like "Invoice #", "Inv No", "Credit Note #", "Reference", "Doc #".
- **account_number**: The customer's account number if present. Not required — omit if not found.
- **total**: The total amount as a decimal string (e.g., "1234.56"). Use the grand total or amount due. For credits, use the credit amount as a positive number. Numbers in parentheses indicate credits — extract them as positive values.
- **explanation**: Only use this when you cannot find any valid invoices. Provide a detailed reason (e.g., "document is blank", "PDF contains only images with no extractable text", "document is a cover letter with no invoice data").
IMPORTANT:
- Do NOT skip entries because some fields are missing. Extract what you can.
- For statements/summaries, each row in an invoice table is a separate invoice entry.
- If OCR fails completely and no text can be extracted at all, return an array with one object containing only the explanation field.
- Your FINAL response must be ONLY a JSON array. Do NOT wrap it in markdown code blocks. Do NOT add any prose before or after the JSON."""
- For statements/summaries, each row in an invoice table is a separate entry in the invoices array.
- If OCR fails completely and no text can be extracted at all, set the explanation field to indicate why."""
INVOICE_TOOL = {
"type": "function",
"function": {
"name": "parsed_invoices",
"description": "Record all extracted invoices and credit notes from the document. Include every invoice found in the invoices array.",
"parameters": {
"type": "object",
"properties": {
"invoices": {
"description": "Array of all invoices and credit notes extracted from the document. Include every one you find.",
"type": "array",
"items": {
"type": "object",
"properties": {
"customer_identifier": {
"description": "The customer's name. e.g., ABC Corporation, Microsoft, etc.",
"type": "string"
},
"vendor_identifier": {
"description": "The vendor's name",
"type": "string"
},
"date": {
"description": "Invoice date in ISO 8601 format (YYYY-MM-DD).",
"type": "string",
"format": "date"
},
"invoice_number": {
"description": "Unique invoice number for the transaction.",
"type": "string"
},
"account_number": {
"description": "Customer's account number associated with the invoice. Not always present on the invoice.",
"type": "string"
},
"total": {
"description": "Total amount of the invoice, including taxes and fees. It should be a decimal number as a string.",
"type": "string",
"pattern": "^\\d+(\\.\\d{1,2})?$"
}
},
"required": ["customer_identifier", "vendor_identifier", "date", "invoice_number", "total"],
"additionalProperties": False
}
},
"explanation": {
"description": "Only use this when you cannot find any valid invoices. Provide a detailed reason (e.g., 'document is blank', 'PDF contains only images with no extractable text', 'document is a cover letter with no invoice data').",
"type": "string"
}
}
}
}
}
def analyze_pdf(pdf_path):
@@ -80,12 +131,18 @@ def analyze_pdf(pdf_path):
],
},
],
tools=[INVOICE_TOOL],
)
text = response.choices[0].message.content
match = re.search(r'```(?:json)?\s*\n(.*?)\n```', text, re.DOTALL)
if match:
text = match.group(1)
return text
message = response.choices[0].message
if message.tool_calls:
for tool_call in message.tool_calls:
if tool_call.function.name == "parsed_invoices":
data = json.loads(tool_call.function.arguments)
return data.get("invoices", [])
return []
def analyze_url(url):
@@ -98,6 +155,11 @@ def analyze_url(url):
def handler(event, context):
print(event)
url = event['url']
print("URL IS", url)
return analyze_url(url)
if "pdf_base64" in event:
pdf_path = "/tmp/invoice.pdf"
with open(pdf_path, "wb") as f:
f.write(base64.b64decode(event["pdf_base64"]))
return analyze_pdf(pdf_path)
if "url" in event:
return analyze_url(event["url"])
raise ValueError("event must contain 'url' or 'pdf_base64'")

26
invoke_lambda.sh Executable file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -euo pipefail
PDF_PATH="${1:-tests/SWCPI25011315283.pdf}"
ENVIRONMENT="${2:-test}"
if [ ! -f "$PDF_PATH" ]; then
echo "Error: PDF file not found: $PDF_PATH"
exit 1
fi
FUNCTION_NAME="glimpse2-${ENVIRONMENT}"
PAYLOAD_FILE=$(mktemp)
python3 -c "import base64, json, sys; json.dump({'pdf_base64': base64.b64encode(open(sys.argv[1], 'rb').read()).decode()}, open(sys.argv[2], 'w'))" "$PDF_PATH" "$PAYLOAD_FILE"
echo "Invoking ${FUNCTION_NAME} with ${PDF_PATH}..."
aws lambda invoke \
--function-name "$FUNCTION_NAME" \
--payload file://"$PAYLOAD_FILE" \
--cli-binary-format raw-in-base64-out \
/tmp/lambda_response.json
rm -f "$PAYLOAD_FILE"
echo "Response:"
python3 -m json.tool /tmp/lambda_response.json 2>/dev/null || cat /tmp/lambda_response.json

27
main.tf
View File

@@ -1,3 +1,16 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.region
}
data "aws_iam_policy_document" "assume_role" {
statement {
effect = "Allow"
@@ -13,11 +26,11 @@ data "aws_iam_policy_document" "assume_role" {
resource "null_resource" "pip_install" {
triggers = {
shell_hash = "${sha256(file("${path.module}/requirements.txt"))}"
shell_hash = "${sha256(file("${path.module}/pyproject.toml"))}"
}
provisioner "local-exec" {
command = "python3 -m pip install -r requirements.txt -t ${path.module}/layer/python"
command = "uv pip compile ${path.module}/pyproject.toml --python 3.11 --no-header -o /tmp/layer-requirements.txt && uv pip install -r /tmp/layer-requirements.txt --python 3.11 -t ${path.module}/layer/python"
}
}
@@ -29,7 +42,7 @@ data "archive_file" "layer" {
}
resource "aws_lambda_layer_version" "layer" {
layer_name = "openai-layer"
layer_name = "openai-layer-${local.env}"
filename = data.archive_file.layer.output_path
source_code_hash = data.archive_file.layer.output_base64sha256
compatible_runtimes = ["python3.11"]
@@ -38,7 +51,7 @@ resource "aws_lambda_layer_version" "layer" {
resource "aws_iam_role" "iam_for_lambda" {
name = "glimpse2"
name = "glimpse2-${local.env}"
assume_role_policy = data.aws_iam_policy_document.assume_role.json
}
@@ -52,11 +65,11 @@ resource "aws_lambda_function" "test_lambda" {
# If the file is not in the current working directory you will need to include a
# path.module in the filename.
filename = "lambda_function_payload.zip"
function_name = "glimpse2"
function_name = "glimpse2-${local.env}"
role = aws_iam_role.iam_for_lambda.arn
handler = "main.handler"
memory_size = 512
timeout = 30
timeout = 60
source_code_hash = data.archive_file.lambda.output_base64sha256
layers = [aws_lambda_layer_version.layer.arn]
@@ -65,7 +78,7 @@ resource "aws_lambda_function" "test_lambda" {
environment {
variables = {
foo = "bar"
environment = local.env
}
}
}

1
prod.tfvars Normal file
View File

@@ -0,0 +1 @@
environment = "prod"

View File

@@ -0,0 +1,313 @@
{
"version": 4,
"terraform_version": "1.15.1",
"serial": 8,
"lineage": "d233b79d-da3f-cd9d-4b62-af1c850901ee",
"outputs": {},
"resources": [
{
"mode": "data",
"type": "archive_file",
"name": "lambda",
"provider": "provider[\"registry.terraform.io/hashicorp/archive\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"exclude_symlink_directories": null,
"excludes": null,
"id": "9d3e0e20184ca740cf3ea4340de29c39affb671d",
"output_base64sha256": "y9M2eCZjnOi+6H60vC4z+HW95OP9GVC0Icw3Yc3xIvU=",
"output_base64sha512": "YbENaC7DYFAI6nJLrnOR99yZx8zFjnboHpcQGRD0/MKuPi+B6oy6l4NsnFAekayBOWddxZquWHTcqZcx9LiCdQ==",
"output_file_mode": null,
"output_md5": "fcfa112d0c05b2a40c72445a7438b356",
"output_path": "lambda_function_payload.zip",
"output_sha": "9d3e0e20184ca740cf3ea4340de29c39affb671d",
"output_sha256": "cbd3367826639ce8bee87eb4bc2e33f875bde4e3fd1950b421cc3761cdf122f5",
"output_sha512": "61b10d682ec3605008ea724bae7391f7dc99c7ccc58e76e81e97101910f4fcc2ae3e2f81ea8cba97836c9c501e91ac8139675dc59aae5874dca99731f4b88275",
"output_size": 12212,
"source": [],
"source_content": null,
"source_content_filename": null,
"source_dir": "./code",
"source_file": null,
"type": "zip"
},
"sensitive_attributes": [],
"identity_schema_version": 0
}
]
},
{
"mode": "data",
"type": "archive_file",
"name": "layer",
"provider": "provider[\"registry.terraform.io/hashicorp/archive\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"exclude_symlink_directories": null,
"excludes": null,
"id": "b2027e85f6c1607a31456d9bab04adea560c124a",
"output_base64sha256": "dB5NITnNHiiWWQtFv9f3eYWRilrtiE60AJNMWRadSlA=",
"output_base64sha512": "YSSHtd8poCa26moOzdrQBJ8zuSK2L2N7XOIJq7KgDerdfbty2gPkcNi7Y/7jQ1UHP++Wft9vZO3P0zYO6T5tmA==",
"output_file_mode": null,
"output_md5": "777cb1543745e89136e2e9efe52b7dee",
"output_path": "./layer.zip",
"output_sha": "b2027e85f6c1607a31456d9bab04adea560c124a",
"output_sha256": "741e4d2139cd1e2896590b45bfd7f77985918a5aed884eb400934c59169d4a50",
"output_sha512": "612487b5df29a026b6ea6a0ecddad0049f33b922b62f637b5ce209abb2a00deadd7dbb72da03e470d8bb63fee34355073fef967edf6f64edcfd3360ee93e6d98",
"output_size": 7103838,
"source": [],
"source_content": null,
"source_content_filename": null,
"source_dir": "./layer",
"source_file": null,
"type": "zip"
},
"sensitive_attributes": [],
"identity_schema_version": 0
}
]
},
{
"mode": "data",
"type": "aws_iam_policy_document",
"name": "assume_role",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"id": "2690255455",
"json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"sts:AssumeRole\",\n \"Principal\": {\n \"Service\": \"lambda.amazonaws.com\"\n }\n }\n ]\n}",
"minified_json": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"}}]}",
"override_json": null,
"override_policy_documents": null,
"policy_id": null,
"source_json": null,
"source_policy_documents": null,
"statement": [
{
"actions": [
"sts:AssumeRole"
],
"condition": [],
"effect": "Allow",
"not_actions": [],
"not_principals": [],
"not_resources": [],
"principals": [
{
"identifiers": [
"lambda.amazonaws.com"
],
"type": "Service"
}
],
"resources": [],
"sid": ""
}
],
"version": "2012-10-17"
},
"sensitive_attributes": [],
"identity_schema_version": 0
}
]
},
{
"mode": "managed",
"type": "aws_iam_role",
"name": "iam_for_lambda",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"arn": "arn:aws:iam::695105795926:role/glimpse2-test",
"assume_role_policy": "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"}}],\"Version\":\"2012-10-17\"}",
"create_date": "2026-05-27T17:09:01Z",
"description": "",
"force_detach_policies": false,
"id": "glimpse2-test",
"inline_policy": [],
"managed_policy_arns": [],
"max_session_duration": 3600,
"name": "glimpse2-test",
"name_prefix": "",
"path": "/",
"permissions_boundary": "",
"tags": {},
"tags_all": {},
"unique_id": "AROA2DV4IW5LLMAWHIGZQ"
},
"sensitive_attributes": [],
"identity_schema_version": 0,
"private": "bnVsbA==",
"dependencies": [
"data.aws_iam_policy_document.assume_role"
]
}
]
},
{
"mode": "managed",
"type": "aws_lambda_function",
"name": "test_lambda",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"architectures": [
"x86_64"
],
"arn": "arn:aws:lambda:us-east-1:695105795926:function:glimpse2-test",
"code_sha256": "y9M2eCZjnOi+6H60vC4z+HW95OP9GVC0Icw3Yc3xIvU=",
"code_signing_config_arn": "",
"dead_letter_config": [],
"description": "",
"environment": [
{
"variables": {
"environment": "test"
}
}
],
"ephemeral_storage": [
{
"size": 512
}
],
"file_system_config": [],
"filename": "lambda_function_payload.zip",
"function_name": "glimpse2-test",
"handler": "main.handler",
"id": "glimpse2-test",
"image_config": [],
"image_uri": "",
"invoke_arn": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:695105795926:function:glimpse2-test/invocations",
"kms_key_arn": "",
"last_modified": "2026-05-27T17:11:46.000+0000",
"layers": [
"arn:aws:lambda:us-east-1:695105795926:layer:openai-layer-test:1"
],
"logging_config": [
{
"application_log_level": "",
"log_format": "Text",
"log_group": "/aws/lambda/glimpse2-test",
"system_log_level": ""
}
],
"memory_size": 512,
"package_type": "Zip",
"publish": false,
"qualified_arn": "arn:aws:lambda:us-east-1:695105795926:function:glimpse2-test:$LATEST",
"qualified_invoke_arn": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:695105795926:function:glimpse2-test:$LATEST/invocations",
"replace_security_groups_on_destroy": null,
"replacement_security_group_ids": null,
"reserved_concurrent_executions": -1,
"role": "arn:aws:iam::695105795926:role/glimpse2-test",
"runtime": "python3.11",
"s3_bucket": null,
"s3_key": null,
"s3_object_version": null,
"signing_job_arn": "",
"signing_profile_version_arn": "",
"skip_destroy": false,
"snap_start": [],
"source_code_hash": "y9M2eCZjnOi+6H60vC4z+HW95OP9GVC0Icw3Yc3xIvU=",
"source_code_size": 12212,
"tags": {},
"tags_all": {},
"timeout": 60,
"timeouts": null,
"tracing_config": [
{
"mode": "PassThrough"
}
],
"version": "$LATEST",
"vpc_config": []
},
"sensitive_attributes": [],
"identity_schema_version": 0,
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6NjAwMDAwMDAwMDAwLCJ1cGRhdGUiOjYwMDAwMDAwMDAwMH19",
"dependencies": [
"aws_iam_role.iam_for_lambda",
"aws_lambda_layer_version.layer",
"data.archive_file.lambda",
"data.archive_file.layer",
"data.aws_iam_policy_document.assume_role",
"null_resource.pip_install"
]
}
]
},
{
"mode": "managed",
"type": "aws_lambda_layer_version",
"name": "layer",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"arn": "arn:aws:lambda:us-east-1:695105795926:layer:openai-layer-test:1",
"code_sha256": "dB5NITnNHiiWWQtFv9f3eYWRilrtiE60AJNMWRadSlA=",
"compatible_architectures": [],
"compatible_runtimes": [
"python3.11"
],
"created_date": "2026-05-27T17:09:07.743+0000",
"description": "",
"filename": "./layer.zip",
"id": "arn:aws:lambda:us-east-1:695105795926:layer:openai-layer-test:1",
"layer_arn": "arn:aws:lambda:us-east-1:695105795926:layer:openai-layer-test",
"layer_name": "openai-layer-test",
"license_info": "",
"s3_bucket": null,
"s3_key": null,
"s3_object_version": null,
"signing_job_arn": "",
"signing_profile_version_arn": "",
"skip_destroy": false,
"source_code_hash": "dB5NITnNHiiWWQtFv9f3eYWRilrtiE60AJNMWRadSlA=",
"source_code_size": 7103838,
"version": "1"
},
"sensitive_attributes": [],
"identity_schema_version": 0,
"private": "bnVsbA==",
"dependencies": [
"data.archive_file.layer",
"null_resource.pip_install"
]
}
]
},
{
"mode": "managed",
"type": "null_resource",
"name": "pip_install",
"provider": "provider[\"registry.terraform.io/hashicorp/null\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"id": "5491774440303221650",
"triggers": {
"shell_hash": "84016380c6c240dd563a10e364ece2d65f4ad6c7313b2dd69cefbeb949fcfa4b"
}
},
"sensitive_attributes": [],
"identity_schema_version": 0
}
]
}
],
"check_results": null
}

View File

@@ -0,0 +1,313 @@
{
"version": 4,
"terraform_version": "1.15.1",
"serial": 6,
"lineage": "d233b79d-da3f-cd9d-4b62-af1c850901ee",
"outputs": {},
"resources": [
{
"mode": "data",
"type": "archive_file",
"name": "lambda",
"provider": "provider[\"registry.terraform.io/hashicorp/archive\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"exclude_symlink_directories": null,
"excludes": null,
"id": "076a08927a351c0f32ee35bce706df144469e677",
"output_base64sha256": "JhTe97YTSvuFlvDFGzhFP+f6yE7Rn6HSp2Y1SYVlOVY=",
"output_base64sha512": "P1Z89ahd14HUlbP7q8yNoFmZPu6B9w95stgmbqEkpWdx1NhJwdiNN4iYDqdHJI/q6cdzE1xLkU8wxwyDIWZj+Q==",
"output_file_mode": null,
"output_md5": "5d9102792c60073f6c15da416babe408",
"output_path": "lambda_function_payload.zip",
"output_sha": "076a08927a351c0f32ee35bce706df144469e677",
"output_sha256": "2614def7b6134afb8596f0c51b38453fe7fac84ed19fa1d2a766354985653956",
"output_sha512": "3f567cf5a85dd781d495b3fbabcc8da059993eee81f70f79b2d8266ea124a56771d4d849c1d88d3788980ea747248feae9c773135c4b914f30c70c83216663f9",
"output_size": 12141,
"source": [],
"source_content": null,
"source_content_filename": null,
"source_dir": "./code",
"source_file": null,
"type": "zip"
},
"sensitive_attributes": [],
"identity_schema_version": 0
}
]
},
{
"mode": "data",
"type": "archive_file",
"name": "layer",
"provider": "provider[\"registry.terraform.io/hashicorp/archive\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"exclude_symlink_directories": null,
"excludes": null,
"id": "b2027e85f6c1607a31456d9bab04adea560c124a",
"output_base64sha256": "dB5NITnNHiiWWQtFv9f3eYWRilrtiE60AJNMWRadSlA=",
"output_base64sha512": "YSSHtd8poCa26moOzdrQBJ8zuSK2L2N7XOIJq7KgDerdfbty2gPkcNi7Y/7jQ1UHP++Wft9vZO3P0zYO6T5tmA==",
"output_file_mode": null,
"output_md5": "777cb1543745e89136e2e9efe52b7dee",
"output_path": "./layer.zip",
"output_sha": "b2027e85f6c1607a31456d9bab04adea560c124a",
"output_sha256": "741e4d2139cd1e2896590b45bfd7f77985918a5aed884eb400934c59169d4a50",
"output_sha512": "612487b5df29a026b6ea6a0ecddad0049f33b922b62f637b5ce209abb2a00deadd7dbb72da03e470d8bb63fee34355073fef967edf6f64edcfd3360ee93e6d98",
"output_size": 7103838,
"source": [],
"source_content": null,
"source_content_filename": null,
"source_dir": "./layer",
"source_file": null,
"type": "zip"
},
"sensitive_attributes": [],
"identity_schema_version": 0
}
]
},
{
"mode": "data",
"type": "aws_iam_policy_document",
"name": "assume_role",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"id": "2690255455",
"json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"sts:AssumeRole\",\n \"Principal\": {\n \"Service\": \"lambda.amazonaws.com\"\n }\n }\n ]\n}",
"minified_json": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"}}]}",
"override_json": null,
"override_policy_documents": null,
"policy_id": null,
"source_json": null,
"source_policy_documents": null,
"statement": [
{
"actions": [
"sts:AssumeRole"
],
"condition": [],
"effect": "Allow",
"not_actions": [],
"not_principals": [],
"not_resources": [],
"principals": [
{
"identifiers": [
"lambda.amazonaws.com"
],
"type": "Service"
}
],
"resources": [],
"sid": ""
}
],
"version": "2012-10-17"
},
"sensitive_attributes": [],
"identity_schema_version": 0
}
]
},
{
"mode": "managed",
"type": "aws_iam_role",
"name": "iam_for_lambda",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"arn": "arn:aws:iam::695105795926:role/glimpse2-test",
"assume_role_policy": "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"}}],\"Version\":\"2012-10-17\"}",
"create_date": "2026-05-27T17:09:01Z",
"description": "",
"force_detach_policies": false,
"id": "glimpse2-test",
"inline_policy": [],
"managed_policy_arns": [],
"max_session_duration": 3600,
"name": "glimpse2-test",
"name_prefix": "",
"path": "/",
"permissions_boundary": "",
"tags": null,
"tags_all": {},
"unique_id": "AROA2DV4IW5LLMAWHIGZQ"
},
"sensitive_attributes": [],
"identity_schema_version": 0,
"private": "bnVsbA==",
"dependencies": [
"data.aws_iam_policy_document.assume_role"
]
}
]
},
{
"mode": "managed",
"type": "aws_lambda_function",
"name": "test_lambda",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"architectures": [
"x86_64"
],
"arn": "arn:aws:lambda:us-east-1:695105795926:function:glimpse2-test",
"code_sha256": "JhTe97YTSvuFlvDFGzhFP+f6yE7Rn6HSp2Y1SYVlOVY=",
"code_signing_config_arn": "",
"dead_letter_config": [],
"description": "",
"environment": [
{
"variables": {
"environment": "test"
}
}
],
"ephemeral_storage": [
{
"size": 512
}
],
"file_system_config": [],
"filename": "lambda_function_payload.zip",
"function_name": "glimpse2-test",
"handler": "main.handler",
"id": "glimpse2-test",
"image_config": [],
"image_uri": "",
"invoke_arn": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:695105795926:function:glimpse2-test/invocations",
"kms_key_arn": "",
"last_modified": "2026-05-27T17:09:08.994+0000",
"layers": [
"arn:aws:lambda:us-east-1:695105795926:layer:openai-layer-test:1"
],
"logging_config": [
{
"application_log_level": "",
"log_format": "Text",
"log_group": "/aws/lambda/glimpse2-test",
"system_log_level": ""
}
],
"memory_size": 512,
"package_type": "Zip",
"publish": false,
"qualified_arn": "arn:aws:lambda:us-east-1:695105795926:function:glimpse2-test:$LATEST",
"qualified_invoke_arn": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:695105795926:function:glimpse2-test:$LATEST/invocations",
"replace_security_groups_on_destroy": null,
"replacement_security_group_ids": null,
"reserved_concurrent_executions": -1,
"role": "arn:aws:iam::695105795926:role/glimpse2-test",
"runtime": "python3.11",
"s3_bucket": null,
"s3_key": null,
"s3_object_version": null,
"signing_job_arn": "",
"signing_profile_version_arn": "",
"skip_destroy": false,
"snap_start": [],
"source_code_hash": "JhTe97YTSvuFlvDFGzhFP+f6yE7Rn6HSp2Y1SYVlOVY=",
"source_code_size": 12141,
"tags": null,
"tags_all": {},
"timeout": 60,
"timeouts": null,
"tracing_config": [
{
"mode": "PassThrough"
}
],
"version": "$LATEST",
"vpc_config": []
},
"sensitive_attributes": [],
"identity_schema_version": 0,
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6NjAwMDAwMDAwMDAwLCJ1cGRhdGUiOjYwMDAwMDAwMDAwMH19",
"dependencies": [
"aws_iam_role.iam_for_lambda",
"aws_lambda_layer_version.layer",
"data.archive_file.lambda",
"data.archive_file.layer",
"data.aws_iam_policy_document.assume_role",
"null_resource.pip_install"
]
}
]
},
{
"mode": "managed",
"type": "aws_lambda_layer_version",
"name": "layer",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"arn": "arn:aws:lambda:us-east-1:695105795926:layer:openai-layer-test:1",
"code_sha256": "dB5NITnNHiiWWQtFv9f3eYWRilrtiE60AJNMWRadSlA=",
"compatible_architectures": null,
"compatible_runtimes": [
"python3.11"
],
"created_date": "2026-05-27T17:09:07.743+0000",
"description": "",
"filename": "./layer.zip",
"id": "arn:aws:lambda:us-east-1:695105795926:layer:openai-layer-test:1",
"layer_arn": "arn:aws:lambda:us-east-1:695105795926:layer:openai-layer-test",
"layer_name": "openai-layer-test",
"license_info": "",
"s3_bucket": null,
"s3_key": null,
"s3_object_version": null,
"signing_job_arn": "",
"signing_profile_version_arn": "",
"skip_destroy": false,
"source_code_hash": "dB5NITnNHiiWWQtFv9f3eYWRilrtiE60AJNMWRadSlA=",
"source_code_size": 7103838,
"version": "1"
},
"sensitive_attributes": [],
"identity_schema_version": 0,
"private": "bnVsbA==",
"dependencies": [
"data.archive_file.layer",
"null_resource.pip_install"
]
}
]
},
{
"mode": "managed",
"type": "null_resource",
"name": "pip_install",
"provider": "provider[\"registry.terraform.io/hashicorp/null\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"id": "5491774440303221650",
"triggers": {
"shell_hash": "84016380c6c240dd563a10e364ece2d65f4ad6c7313b2dd69cefbeb949fcfa4b"
}
},
"sensitive_attributes": [],
"identity_schema_version": 0
}
]
}
],
"check_results": null
}

1
test.tfvars Normal file
View File

@@ -0,0 +1 @@
environment = "test"

15
variables.tf Normal file
View File

@@ -0,0 +1,15 @@
variable "environment" {
description = "Deployment environment name"
type = string
default = "prod"
}
variable "region" {
description = "AWS region"
type = string
default = "us-east-1"
}
locals {
env = terraform.workspace == "default" ? "prod" : terraform.workspace
}