
The pigeon coop & the back room: A wiseguy's guide to not screwing up the message
I like to write stories to better explain problems I have or concepts I want to share. I still want the message to be clear, concise, and easy to digest, so I’ll give you a glossary to refer back to when reading the story if it it doesn’t click the first time.
Prologue: Because configuring shit is honestly 90% of it
Alright, let's get one thing straight. Setting up cloud infrastructure, wrestling with configurations, deciphering cryptic error messages – sometimes it feels less like software engineering and more like trying to assemble IKEA furniture in the dark during an earthquake while someone shouts jargon at you. I've read the manuals, I've stared at the diagrams, and often, my brain just goes... static.
See, my mind doesn't always click with purely technical terms dropped like anvils from Mount Olympus. It likes stories. It needs analogies, maybe slightly weird ones, to make things stick. I figure, if the core concept makes sense, the fancy names will follow (or at least be Google-able). If I have to imagine mobsters using a secret pigeon network to understand AWS SNS, then so be it.
So, we're taking a detour from the usual dry tech talk. We're heading to Mama Rosa's Pizza in New York City. Why? Because sometimes, explaining secure, asynchronous messaging feels a lot like navigating the delicate communication needs of a family... business.
Is this the official AWS documentation? Absolutely not. Is it slightly ridiculous? Probably. But maybe, just maybe, translating configuration hell and debugging cloud services into the language of pizza, pigeons, and wiseguys will actually make it clearer. At the very least, it might be more fun than reading another spec sheet.
Grab a metaphorical slice, keep your wits about you, and let's dive into how John tried to keep The Boss happy without ending up wearing concrete shoes.
The scene
Mama Rosa’s Pizza, NYC. Best slice in the tristate? Eh. Also, the nerve center for this neighborhood’s… let’s call it “import/export consulting”. I’m John, I sling dough, wipe tables, and sometimes, I make the computers do stuff The Boss wants.
The problem: Getting the word out (quietly)
Imagine this: The Boss walks in, smelling of garlic and authority. “Johnny”, he says, polishing his pinky ring. “We need a new way. Tony’s in the kitchen finishing the… baconeggandcheese… he needs to tell Sal out front with the delivery car. Now. No phones, no pagers, too risky. Make it happen.”
Right. Baconeggandcheese. So, I, ol John, need a secure, instant message from the Kitchen Crew (one system) to the Delivery Crew (another system). Untraceable.
My bright idea? We set up a private Pigeon Coop Network. It’s slick. The kitchen sends a coded message: extra garlic on #12 to a specific Handler at the coop. Only the Lofts registered with that guy — like Sal’s lookout post — get the pigeon. Fast, reliable, no digital trail. What could go wrong?
The rule: Don’t test on live pigeons
Now, The Boss has one rule thicker than a snicker: you don’t mess up a live run. Sending a test “baconeggandcheese” signal before the actual baconeggandcheese is ready? That’s a one-way ticket to swimming lessons over near Dumbo.
So, now I’m looking for a practice area.
Where the hell am I going to find a practice area?
I requisition the dusty back room and build a Model Pizza Kitchen & Fake Street Corner. It’s a perfect replica—fake ovens, cardboard delivery car, the works. It even has its own Model Pigeon Coop (I call it model because it’s not real) that works just like the real one, but it’s totally self-contained. No messages get out.
To make setup and teardown faster (The Boss hates clutter), I use my Pop-Up Crime Scene Kit. I made it myself (or at least I tell myself I did). It’s this neat box—pop it open, boom, instant model kitchen and fake street corner. Close it, poof, it’s gone. Keeps the real operation clean.
My first attempts: ay ay ay
I rig up the kit, get the model kitchen running, set up a fake Delivery Crew receiver, and try sending a test message. “PINEAPPLE BELONGS ON PIZZA”—something guaranteed not to be real code.
Result: nada. Sal’s cardboard cutout counterpart hears nothing. The pigeons ain’t flying. Shit. Why? Grab an espresso, Johnny, it’s gonna be a long night.
- Stumble #1: Using the Wrong Page in the Codebook (AWS Configuration &
awslocal
)- See, the Family has an Official Ledger & Codebook (our AWS
config
&credentials
files) locked in the back office safe. It's got all the secret addresses and access codes for the real Pigeon Coop Network. But the Model Pigeon Coop in the back room uses different, temporary codes (likeaccess_key_id = test
). My message sender device (application.yaml
) was still reading from the real ledger page! Of course it didn't work. I also needed to use the right command words (awslocal
or specific endpoint settings) to signal I was talking to the model coop, not the real deal. Details, Johnny, details!
- See, the Family has an Official Ledger & Codebook (our AWS
- Stumble #2: Assholes & The Secret Handshake (CSRF Protection)
- Okay, fixed the codebook issue. Now? The fake Delivery Crew receiver shouts
YA THOUGHT! (401 Unauthorized)
. Turns out, Sal's real lookout post has security – a Secret Handshake (CSRF Protection). It stops rival crews (hackers) from sending fake messages ("Deliver the calzones... to precinct 7") trying to mess us up. Any message needs the handshake (a CSRF Token) to be accepted. My messages from the Model Kitchen? They didn't know the handshake! I had to have a word with the "security" on the fake lookout post (SecurityConfig): "Yo, messages from this specific model kitchen are cool. It's me, Johnny, testing. Let 'em through without the handshake for now, okay? Just these practice runs."
- Okay, fixed the codebook issue. Now? The fake Delivery Crew receiver shouts
- Stumble #3: Shouting Inside the Walk-In Freezer (
localhost
Trap)- This one almost had me pulling my hair out. Everything seemed right, but still no message. Then it hit me: The Model Kitchen (LocalStack running in my Pop-Up Kit/Testcontainers) is like its own little walk-in freezer. When I told my sender inside the freezer to send a message to the receiver at
this_freezer:8080
(localhost:8080
), it was just echoing off the frozen salami! It wasn't pointing to the receiver's location outside the freezer, on the main floor plan of the back room. I needed the address that navigated out of the freezer to the correct spot. (My Pop-Up Kit had a special way to figure out this address). It's like yelling directions inside a box – nobody outside can hear you right.
- This one almost had me pulling my hair out. Everything seemed right, but still no message. Then it hit me: The Model Kitchen (LocalStack running in my Pop-Up Kit/Testcontainers) is like its own little walk-in freezer. When I told my sender inside the freezer to send a message to the receiver at
Making the sauce right: The working setup for CLI
Finally, clarity. Like a perfect tomato sauce, it needed the right ingredients, in the right order:
- Get your configs straight: In the back office safe (
~/.aws/
), create two clear entries in the Ledger & Codebook: one for the real Pigeon Network, one for the Model Pigeon Coop (localstack
). Make sure the model one lists the back room's address (endpoint_url =
http://localhost:4566
) and the practice codes (test
/test
). Triple-check that your message sender device (application.yaml
) is set to use thelocalstack
profile from the codebook for testing.# ~/.aws/config --> Page for the Model Coop [profile localstack] region=us-east-1 # Doesn't matter much for model, but keep it consistent output=json endpoint_url = http://localhost:4566 # Address of the Model Coop # ~/.aws/credentials --> Practice Access Codes [localstack] aws_access_key_id = test aws_secret_access_key = test # application.yaml --> Sender Device Instructions spring: cloud: aws: sns: region: us-east-1 # Match the profile
- Set up a handler in the model coop (create topic): Give the order, specifying the
localstack
profile. Remember the Handler's official designation (TopicArn
). Bash# Order: "New Handler for baconeggandcheese signals, Model Coop Only" aws sns create-topic --name cannoli-signals --profile localstack
- Register Sal’s fake loft(subscribe to topic): Tell the "baconeggandcheese" handler where the fake Delivery Crew lookout post (
notification_endpoint
) is located. Use the address reachable from the Model Kitchen's perspective. Wait for the confirmation pigeon and signal back.# Order: "Fake Sal Loft listens to baconeggandcheese Handler" aws sns subscribe \ --topic-arn <TopicArn_from_step_2> \ --protocol http \ --notification-endpoint <Address_of_Fake_Sal_Loft> \ --profile localstack
- Send a Test Pigeon (Publish Message): Let's see if this bird flies.
# Order: "Send 'Test Batch #1' via baconeggandcheese Handler" aws sns publish \ --topic-arn <TopicArn_from_step_2> \ --message '{"type": "Test#1", "status": "ReadyForPickup...NotReally"}' \ --profile localstack
AYE! The test message flew through the Model Pigeon Coop, got past the (correctly instructed) security on the fake lookout post, arrived at the right fake address, and the cardboard Sal got the word.
I wiped the sweat off my brow. The system worked. No real pigeons were harmed (or alerted), no sleep schedules with the fishes were arranged. Now, to hook it up to the real network... carefully. The Boss just nodded, a hint of baconeggandcheese still on his lapel. Another day at Mama Rosa's.
host.docker.internal
.Mama Rosa’s glossary of terms
Think of this as the cheat sheet John probably wishes he had. It maps the story elements back to the actual technical concepts being wrestled with.
Name | Actual | Description |
Mama Rosa’s Pizza / The Family Business | Overall application or system | The overall application or system you’re building. |
The Boss | Person demanding results | The person who demands results without knowing the how. |
John | Developer | You (or maybe not), the dev, trying to make this stuff work under pressure. |
Kitchen Crew / KitchenOps | Message sender | The specific part of your system sending the message or event (e.g. a microservice that completes a task). |
Delivery Crew / DeliveryDispatch / Sal / Sal’s Lookout Post | Message receiver | The specific part of your system receiving the message or event (e.g. another microservice that needs to react. A subscriber). |
“baconeggandcheese” / coded message | Message or event | Whatever you’re sending between the services/components in your system (event notification or payload or whatever you got in your back pocket). |
Pigeon Coop Network | AWS Simple Notification Service (AWS SNS) | The managed cloud service used for pub-sub messaging. |
Handler (at the coop) | SNS Topic | Specific channels or mailing lists within SNS; you publish messages to a Topic. |
Lofts / Sal’s (Fake) Loft | SNS Subscription | Defines an endpoint (like your receiving microservice) that is registered to receive messages sent to a specific SNS Topic. |
Model Pizza Kitchen & Fake Street Corner | LocalStack | A tool that runs on your local machine and mimics various AWS cloud services (like SNS) so you can test your code without going broke. |
Model Pigeon Coop | SNS service as emulated by LocalStack | Behaves like the real SNS but it’s running entirely in your local testing environment. |
Pop-up Crime Scene Kit | Testcontainers | A testing library that lets you programmatically start, manage, and stop temporary software environments (like LocalStack) inside Docker containers, making automated testing much easier and cleaner. This is not needed to run your stuff locally. This is helpful for TESTING. USING THAT JUNIT. BING BAM BADDA BOOM. |
Official Ledger & Codebook (in the back office safe) | AWS Configuration & Credentials files | These store your secret access keys and configuration details (like region, output format, and custom endpoint URLs) needed to connect to AWS services. |
Model Coop's Page/Entry (in the Ledger) | AWS Profile | A specific AWS Profile defined within your config/credentials files, set up to connect to your local LocalStack instance. Makes it easy so you don’t have to add a bunch of flags to your CLI. LocalStack even provides a awslocal , so you don’t even need to have any flags. Crazy, huh? |
Message Sender Device | Application's Code and Configuration (e.g., settings in application.yaml , environment variables, code that initializes the AWS client) | This is what actually uses the credentials and configuration to interact with SNS (or LocalStack |
Rival Gangs / Assholes | Malicious actors | Hackers or unintended external requests trying to interact with your system. |
Secret Handshake | CSRF Protection/Token | A security measure to ensure requests come from a trusted source. |
Security (on the lookout post) | Web Security Framework | Your application's Web Security Framework (like Spring Security, or middleware in other frameworks). This enforces rules like checking for the valid Secret Handshake (CSRF token) on incoming requests. |
Walk-In Freezer / Back Room Address (localhost issue) | Docker networking issue | The common localhost networking confusion when using Docker. Inside a container (like the one Testcontainers runs for LocalStack), localhost refers to the container itself, not the machine hosting the container. Connecting to services running on the host from inside the container requires specific addresses (like host.docker.internal or correctly configured Docker networking). |
Orders (AWS CLI Commands) | AWS Command Line Interface (CLI) commands | Standard AWS Command Line Interface (CLI) commands (aws sns create-topic , aws sns subscribe , aws sns publish , etc.). These are used to manually interact with and manage AWS services (or, when configured with the right profile/endpoint, to interact with LocalStack). |