Hi folks, I've got a question about the best way to do some "start-only" DI using the downstream Brooklyn-Terraform project, and I wondered what people's thoughts are on the best way to do something.
The situation is that we have a mid-tier TF and a data-tier TF, and as you might expect we need to pass the data-tier URL to the mid-tier. We currently do this as a config `tf_var.db_url = $brooklyn:entity("data_tier").attributeWhenReady("db_url")`. It works great in almost all cases. Where it doesn't work well is if we stop the data-tier before the mid-tier. In this case when we stop mid-tier, it fails because the attribute sensor `db_url` isn't available and isn't expected to be available. Of course we don't need the `db_url` to tear down the mid-tier, but there's no way currently to indicate that. So what's the best way to indicate that `db_url` is only needed during plan/apply? There are a few options I can think of: (A) Add a `pre_apply.workflow` (and probably a `pre_plan.workflow`, `pre_stop.workflow`, and maybe also `post_<step>.workflow`) config to the terraform entity, providing a way to supply an optional workflow to be run prior to apply/plan. In this workflow we could say `wait db_url = $brooklyn:entity("data_tier").attributeWhenReady("db_url")` then `set-config db_url = db_url`. And the `tf_var.db_url` points at `$brooklyn:config("db_url")`. This means it is only updated on apply, and a `stop` or other `plan` instruction will simply use the last set variable. (And in the `pre_plan.workflow` we could be more forgiving, update config `db_url` if there is a new `db_url` available but otherwise just leave it as it was.) (B) Add new special handling for vars of the form `apply.tf_vars.V` (optionally `plan.tf_vars.V`, `stop.tf_vars.V`) where these vars are only used if that is the step being done. (C) Add a `$brooklyn:if(condition, when_matched, when_unmatched)` function to the DSL in Apache Brooklyn. Then in Brooklyn Terraform we could say something like `$brooklyn:if( { sensor: service.status, equals: starting }, $brooklyn:entity("data_tier").attributeWhenReady("db_url"), $brooklyn:sensor("last_vars.db_url"))`. (D) Add a `depends_on` keyword which creates a relationship between two entities. If such a relationship is present, the dependent entity won't be allowed to start until the dependency is ready, and the dependency isn't allowed to stop until the dependent is stopped. This would solve the problem in a different way, because the `data_tier` wouldn't be allowed to be stopped while the `mid_tier` is active. This is how it is addressed within Terraform. I think I lean towards (A), because although (B) and (C) are more concise, they aren't as clear or as powerful as (A). (D) would be nice but feels like quite a bit more work, and some subtle things to consider around start/stop checking these dependencies. And if enforced out-of-the-box on start/stop likely to be slightly crude and obscure. (D) seems like a nice thing to consider, maybe adding workflow steps to facilitate is, so e.g. as part of (A) a developer could say, e.g. in the `pre_start.workflow` "wait for all dependencies to be ready" and in the `pre_stop.workflow` "wait for all dependents to be stopped", but not something to bake in. Please if you have thoughts on the above, or you can think of other good ways to do it, let me know! Best Alex [1] https://github.com/cloudsoft/brooklyn-terraform