Well, maps as created by %{} are exactly that… They are maps in memory. So you can create them and pass them around, accessing is easy as map_variable[key].
Or you can store it in ETS which might be more optimized than passing around a map if you use a lot of processes and want to avoid copying the full map around or if you need mutability. You need to use functions from :ets to access and build it. It is common to wrap those into an own module.
Or you can use persistent terms if you need access from multiple processes but do not need writes (that often), similar to ETS, you need to use functions :persistent_term for access but its common to wrap them.
What is not possible though, is having some syntax like you propose, as we do not have static variables in a module. Modules only provide functions.
You could mimik your syntax by creating a function which loads the full map from ETS or PS or disk again and returns it, but that would be inefficient, as you’d always need to fully copy the map into your current process for a single key you access.
Elixir is not C#, Elixir is not even class oriented, nor is it mutable, nor does it run on the CLR. There are just things you can’t do due to either different syntax or because of different internals of the VM or because of other things.
If it’s a map that is loaded once and done then persistent_term’ing it might be useful, but honestly I’d just use ETS. It’s already cross process, has multiple ways to look up info, etc…
If it makes sense for the data you’re loading from a file, and if you have it available at compile time, you could compile your lookup module with the data already in it, so you could call LookupModule.lookup("my_table", "my_key"), and your module would have generated something like def lookup("my_table", "my_key"), do: "my_data"