We have experienced the stage topic prefix approach in our project for months. I think we keep doing it but there are some side effects that I have mentioned below.
STAGE AS TOPIC PREFIX
Most of the time messages will routed to IoTCore Rules and will trigger some AWS services like Lambda/S3/Dynamo etc. If you are using serverless this could achive with env variables as follows
...
custom:
myStage: ${opt:stage, self:provider.stage}
STAGES:
- dev
- prod
provider:
name: aws
runtime: nodejs12.x
region: eu-central-1
environment:
STAGE: ${self:custom.myStage}
functions:
someLambdaFunction:
timeout: 180
handler: someLambdaFunction.handler
events:
- iot:
name: "iotRuleName_${self:custom.myStage}"
sqlVersion: "2016-03-23"
sql: "SELECT * as data , topic() as topicName FROM '${self:custom.myStage}/room/+/temperature'"
So when you deploy to serverless app to development environment, the rule name will be iotRuleName_dev
and the rule sql will be like dev/room/+/temperature
But there are some problems:
As you say with this approach, endnodes should know the prefix value.
AWS limits your topic levels as 8 -max 7 forward slashes(/) - so by adding stage as prefix to all topics you basically decrease your limit to 7 AWS IoT Core Quotas
You still have to check for thingName collision. You cant have same thingName in multiple environments at the same time and you would not want to deal with it. Adding stage prefix to thing names could solve confusion. Something like 'DEV-Thing1'
You would also want to consider using basic ingest to reduce costs
STAGE AS REGIONS
It could also possible to split your whole application environments between AWS regions, No collision, no side effects. But you should almost split everything to sleep well in your bad at night. Because accessing different regions entities could cause a big chaos.
CUSTOM APPLICATION
Build your own IoT Core. Well, if you achive this. Do not only use it but sell it.