Module 1: Genai In Production Vs A Notebook

5. Hands-on: inventory of what already exists

Description

Before declaring a single new resource, this lesson does exactly what the "verify before building" discipline — already installed in the previous seven guides — demands: confirm, with real awslocal commands, what exists today in andes-cargo-infra/. Not a prose summary of what previous guides said they built — the exact three commands that would confirm that inventory, run against the inherited infrastructure, with the output they would produce reconstructed field by field from the real HCL and from the deployments those guides already verified.

Connection to the module

Lessons 1 through 4 gave the map, the theory, and the boundary. This lesson is the first one in this module to touch a terminal — this guide's first contact with Andes Cargo's real infrastructure. Everything you confirm here is exactly what lesson 6 is going to assume you already know, and exactly what this guide's M3 is going to extend with bedrock.tf.


This lesson's exact honesty, before the first command

This lesson runs three awslocal commands — events list-rules, lambda list-functions, iam list-roles — against services that are included in LocalStack's free Hobby plan (EventBridge, Lambda, and IAM, the same ones aws-core-services-guide and aws-serverless-and-containers-guide already confirmed and used from their first hands-on lesson). This is different, and it's worth stating precisely, from the limit you'll see in lesson 7 of this same module: there, no free LocalStack plan includes Bedrock, no matter what token you use. Here, the service is available on Hobby — the limit is exclusively about this specific writing environment, which has no LOCALSTACK_AUTH_TOKEN exported, so the LocalStack container never starts (Could not connect to the endpoint URL), the same specific limit, with the same message, you already saw cited in cloud-security-and-guardrails-guide and finops-and-cost-guardrails-guide. On your own machine, with a LocalStack token registered (the Hobby plan is free, it just requires an account), these three commands run for real and return exactly this output — because it's exactly what the previous guides' real, already-applied HCL produced.

Every "What to expect" block in this lesson carries the "(representative)" label, reconstructed field by field against andes-cargo-infra/'s real, verified state at the close of aws-serverless-and-containers-guide — never invented.


Command 1 — The active Lambda functions

awslocal lambda list-functions --query 'Functions[].FunctionName'

What to expect (representative — reconstructed against the final state documented in aws-serverless-and-containers-guide, Module 8, where get-shipment-status is explicitly retired when replaced by the andes-cargo-status-api container):

[
    "process-shipment-manifest",
    "validate-shipment-manifest",
    "notify-shipment-partner"
]

Three functions, none of them AI yet. process-shipment-manifest is the one you already know from lesson 3 of this module. validate-shipment-manifest and notify-shipment-partner are the other two steps of ShipmentManifestWorkflow — pre-validation and post-processing notification —, inherited from aws-serverless-and-containers-guide with this guide never touching them. Notice what does not appear: get-shipment-status existed through that guide's M8, and was deliberately retired when GET /shipments/{shipmentId} migrated from a Lambda integration to an integration with the andes-cargo-status-api container — this inventory reflects that final state, not an intermediate point.


Command 2 — The IAM roles that already exist

awslocal iam list-roles --query 'Roles[].RoleName'

What to expect (representative — same criterion: only the roles the previous guides actually applied against LocalStack, none of the ones marked as representative in their own source guide):

[
    "LambdaManifestProcessorRole",
    "AppServerRole",
    "ShipmentWorkflowExecutionRole",
    "EventBridgeAutomationRole",
    "AndesCargoDeployRole"
]

The first two come from aws-core-services-guideLambdaManifestProcessorRole for process-shipment-manifest, AppServerRole for the instance serving the app. The next two are from aws-serverless-and-containers-guideShipmentWorkflowExecutionRole for ShipmentManifestWorkflow, EventBridgeAutomationRole for EventBridge's rules and schedule. The last one, AndesCargoDeployRole, is from cloud-security-and-guardrails-guide — the deploy role with a trust policy conditioned on GitHub Actions OIDC. No role in this list has any Bedrock-related permission — the naming convention, descriptive PascalCase with a Role suffix, is exactly what you'll see applied to this guide's new role, BedrockManifestExtractorRole, starting in M3.


Command 3 — The EventBridge rules, on both buses

This is the most revealing part of the inventory, and the one that connects directly to lesson 3. Run the command twice — once for each bus that exists today:

awslocal events list-rules --event-bus-name default

What to expect (representative):

{
    "Rules": [
        {
            "Name": "shipment-manifest-uploaded-rule",
            "Arn": "arn:aws:events:us-east-1:000000000000:rule/shipment-manifest-uploaded-rule",
            "EventPattern": "{\"source\":[\"aws.s3\"],\"detail-type\":[\"Object Created\"],\"detail\":{\"bucket\":{\"name\":[\"andes-cargo-shipment-docs\"]},\"object\":{\"key\":[{\"prefix\":\"manifests/\"}]}}}",
            "State": "ENABLED",
            "Description": "Starts ShipmentManifestWorkflow when a new manifest gets uploaded to andes-cargo-shipment-docs",
            "EventBusName": "default"
        }
    ]
}
awslocal events list-rules --event-bus-name andes-cargo-events

What to expect (representative):

{
    "Rules": []
}

Read this carefully — it's this lesson's central finding. The default bus has exactly one rule: the one connecting a manifest upload in S3 to ShipmentManifestWorkflow starting. The custom bus andes-cargo-events — the one ShipmentProcessed and ShipmentDelayed already use to announce themselves every time a shipment gets processed or delayed — has no rule yet. Events do get published, for real, every time the workflow runs successfully — but, today, nothing in andes-cargo-infra/ reacts to them. That's exactly the empty space where ManifestParseFailed is going to appear: this guide's M3 declares the first real rule that bus is going to have, closing a loop the previous guides deliberately left open.


The full inventory, in a single diagram

   ANDES CARGO — INHERITED STATE, AT THE START OF THIS GUIDE

   Active Lambdas                     Active IAM roles
   ─────────────────                  ──────────────────
   process-shipment-manifest          LambdaManifestProcessorRole
   validate-shipment-manifest         AppServerRole
   notify-shipment-partner            ShipmentWorkflowExecutionRole
                                       EventBridgeAutomationRole
                                       AndesCargoDeployRole

   default bus                        andes-cargo-events bus
   ─────────────                      ────────────────────────
   shipment-manifest-uploaded-rule    (no rule yet)
   → starts ShipmentManifestWorkflow     ShipmentProcessed  ┐
                                          ShipmentDelayed    ┴─ published,
                                                                nobody listens

   ═══════════════════════════════════════════════════════════
   What this guide adds, starting in M3:

     BedrockManifestExtractorRole      ← new IAM role
     extract-shipment-manifest-fields  ← new Lambda
     rule on andes-cargo-events        ← listens for ManifestParseFailed
   ═══════════════════════════════════════════════════════════

Common mistakes

Running these commands against your own LocalStack and expecting exactly the same output, without having run the previous seven guides (expectation mistake). What happens: someone jumps straight into this guide, runs lambda list-functions, and only sees an empty list or a subset of these three functions. How to spot it: if your actual output doesn't match this lesson's. How to fix it: this output represents andes-cargo-infra/'s state after completing the previous seven guides, with every terraform apply run in order. If your real inventory is different, the most likely cause is that one of those guides is missing, not an error in this lesson.

Confusing "representative due to missing token" with "representative because the service doesn't exist on Hobby" (reading mistake, the same one lesson 1 of this module already anticipated). What happens: someone reads "(representative)" in this lesson and in lesson 7 of this same module, and assumes the reason is the same in both. How to spot it: if you can't explain, without looking back, why EventBridge/Lambda/IAM run on Hobby but Bedrock doesn't. How to fix it: EventBridge, Lambda, and IAM have been confirmed on LocalStack's free Hobby plan since aws-core-services-guide — this lesson's limit is exclusively that this writing environment has no token exported, something solved by registering for free. Bedrock, in lesson 7, is a different, harder limit: it's not available even with a Hobby token — only the paid Ultimate plan includes it.

Concluding that the andes-cargo-events bus "is useless" because it has no rule (scope mistake). What happens: someone sees "Rules": [] on that bus and concludes it was a mistake to leave it unconnected. How to spot it: if your reaction is "so what's the point of this bus." How to fix it: an EventBridge bus doesn't need a rule for publishing events to it to make sense — it's exactly the decoupling pattern aws-serverless-and-containers-guide taught: the producer (process-shipment-manifest, via ShipmentManifestWorkflow) announces facts without knowing or needing to know who, if anyone, will react. The bus being empty of rules today is precisely the extension space this guide uses — not an oversight, a design that deliberately waited for this guide.


Exercises

Exercise 1 — Explain why get-shipment-status doesn't appear in Command 1. A colleague who only made it through Module 5 of aws-serverless-and-containers-guide asks why this lesson doesn't include that function in the inventory, since they remember it from that guide. Explain to them what changed.

See solution

get-shipment-status existed as a real Lambda function from Module 5 of aws-serverless-and-containers-guide, serving GET /shipments/{shipmentId} through an AWS_PROXY API Gateway integration. In Module 8 of that same guide (the capstone), that integration migrated to HTTP_PROXY, pointing at the andes-cargo-status-api container instead — the same public resource (API Gateway's Resource and Method unchanged), but with a different backend. As a consequence, the get-shipment-status Lambda function gets retired — this inventory, taken at that guide's close, reflects the final state, where that function no longer exists.

Exercise 2 — Predict what would change in Command 3 after completing this guide's M3. Without looking ahead in this guide, predict what would appear in "Rules": [] for the andes-cargo-events bus once M3 declares the AI workload's infrastructure.

See solution

A new rule would appear, structurally analogous to shipment-manifest-uploaded-rule but filtering for the ManifestParseFailed event instead of S3's Object Created — something with a name consistent with the existing convention, for example manifest-parse-failed-rule, with an EventPattern filtering "source": ["andescargo.shipments"] and "detail-type": ["Manifest Parse Failed"], and a target that invokes extract-shipment-manifest-fields. The andes-cargo-events bus, empty of rules today, would then have exactly one — the first real consumer of the events that bus has already been publishing since aws-serverless-and-containers-guide.

Exercise 3 — Explain the difference between "representative due to missing token" and "representative due to plan limit," in your own words. Without looking at this lesson's honesty section, explain to a colleague why this lesson and lesson 7 of this same module use the same "(representative)" label for two different technical reasons.

See solution

A complete answer sounds, roughly, like this: "In this lesson, the three services we're querying — EventBridge, Lambda, IAM — are included in LocalStack's free Hobby plan; the only thing missing is a LOCALSTACK_AUTH_TOKEN exported in this specific writing environment, so the container never starts. Anyone who registers for free and exports their own token would see this exact same output, literally, running for real. In lesson 7, on the other hand, the limit isn't about this environment — it's about the service itself: Bedrock isn't included in any plan below the paid Ultimate tier, so it wouldn't run even with a registered Hobby token. One is a limitation of where I'm writing this guide; the other is a limitation of the service the whole guide teaches you to operate."


Summary and next step

In this lesson you ran — representatively, with the exact reason stated — the real inventory of andes-cargo-infra/: three active Lambda functions, five IAM roles, one rule on the default bus, and zero rules on the andes-cargo-events bus, even though that bus already publishes ShipmentProcessed and ShipmentDelayed for real. You confirmed, with real commands, the exact starting point the rest of this guide builds on, and you saw, with evidence, the empty space ManifestParseFailed is going to occupy starting in M3.

Before moving on you should be able to: name the three active Lambda functions and explain why get-shipment-status is no longer there; explain why this lesson is "(representative)" for a different reason than lesson 7; and describe, without looking back, Command 3's central finding — a bus that publishes events nobody listens to yet.

Lesson 6 changes terrain: instead of taking inventory of what already exists, it maps what Bedrock offers in 2026 — the available model families, verified against current sources, and the underlying reason lesson 3's cheap path stays the default even with that whole catalog available.

Resources

  1. aws-serverless-and-containers-guide, Module 8 (08-project-the-andes-cargo-capstone-deliverable.md) — the source of the inherited system's final state, reconstructed in this lesson.
  2. cloud-security-and-guardrails-guide, Module 2 — the source of AndesCargoDeployRole, this inventory's fifth role.
  3. LocalStack — Pricing — confirmation that EventBridge, Lambda, and IAM are included in the free Hobby plan, unlike Bedrock (lesson 7).
  4. AWS CLI — lambda list-functions · iam list-roles · events list-rules — official references for this lesson's three commands.