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

Reply via email to