Yes, the best way to do this will be to make your charm a "subordinate" for the applications running on the set of machines for which it is relevant.
A subordinate charm is "coupled" to a normal application charm, and it gets installed everywhere that "normal" application charm is installed. Usually, it's used to connect the app up to some sort of ancillary system, like a monitoring system. Once you have established the subordinate relationship, any time the main application is scaled up to more machines, the subordinate will come along too.
So in your example, you probably have a main application, like the hypervisor controller "nova-compute" in OpenStack, which goes on the machines where your code is relevant. You make your charm a subordinate and then deploy it associated with nova-compute. Now your code is everywhere that nova-compute goes.
There are complications to be aware of. The main application will be installed first and THEN your subordinate, so if you need your code to run first, then you need to do it differently. In that case, make your code a primary application charm and deploy it first. Then manually place the other charm units on the same machines using "juju deploy foo --to X" where X is a machine that already has your app on it. This latter approach is ore fiddly because you need to decide where everything goes, and put it there explicitly.