Hi Alex, How does (A) work exactly? What difference does it make if the attributeWhenReady is in a pre-apply workflow or not? Why doesn't the same problem occur as you've described?
Geoff On Mon, 1 May 2023 at 09:21, Alex Heneveld <a...@cloudsoft.io> wrote: > 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 >