This is an automated email from the ASF dual-hosted git repository. heneveld pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/brooklyn-docs.git
commit c59f01d1b1f083d6ea52bde828ac6985c6eb84e8 Author: Alex Heneveld <a...@cloudsoft.io> AuthorDate: Tue May 23 12:18:56 2023 +0100 update children documentation complete, with an example example needs some work --- .../examples/aws-cfn-stacks/aws-cfn-type.bom | 15 +++++++++ .../examples/aws-cfn-stacks/aws-discoverer.yaml | 16 ++++++++++ .../workflow/examples/aws-cfn-stacks/index.md | 35 +++++++++++++++++++++ guide/blueprints/workflow/examples/index.md | 1 + guide/blueprints/workflow/steps/steps.yaml | 36 ++++++++++------------ 5 files changed, 84 insertions(+), 19 deletions(-) diff --git a/guide/blueprints/workflow/examples/aws-cfn-stacks/aws-cfn-type.bom b/guide/blueprints/workflow/examples/aws-cfn-stacks/aws-cfn-type.bom new file mode 100644 index 00000000..5db98302 --- /dev/null +++ b/guide/blueprints/workflow/examples/aws-cfn-stacks/aws-cfn-type.bom @@ -0,0 +1,15 @@ +brooklyn.catalog: + bundle: aws-cfn-discovery-sample + version: 1.0.0-SNAPSHOT + items: + - id: aws-cfn-discovered-stack-sample + item: + type: org.apache.brooklyn.entity.stock.BasicEntity + brooklyn.initializers: + - type: workflow-effector + name: on_update + steps: + - set-entity-name ${item.StackName} + - set-sensor data = ${item} + - set-sensor stack_status = ${item.StackStatus} + # above is just a start, you can check drift, explore resources, etc diff --git a/guide/blueprints/workflow/examples/aws-cfn-stacks/aws-discoverer.yaml b/guide/blueprints/workflow/examples/aws-cfn-stacks/aws-discoverer.yaml new file mode 100644 index 00000000..b82f6e25 --- /dev/null +++ b/guide/blueprints/workflow/examples/aws-cfn-stacks/aws-discoverer.yaml @@ -0,0 +1,16 @@ +name: AWS CloudFormation Discoverer + +services: + - type: workflow-software-process + location: localhost + name: Stacks + + brooklyn.policies: + - type: workflow-policy + brooklyn.config: + name: periodically update children + period: 1m + steps: + - ssh aws cloudformation describe-stacks + - transform output | json | set describe_stacks_output_json + - update-children type aws-cfn-discovered-stack-sample id ${item.StackId} from ${describe_stacks_output_json.Stacks} diff --git a/guide/blueprints/workflow/examples/aws-cfn-stacks/index.md b/guide/blueprints/workflow/examples/aws-cfn-stacks/index.md new file mode 100644 index 00000000..9c5a9465 --- /dev/null +++ b/guide/blueprints/workflow/examples/aws-cfn-stacks/index.md @@ -0,0 +1,35 @@ +--- +title: AWS CloudFormation Stack Discovery +title_in_menu: AWS CFN Stacks +layout: website-normal +--- + +The `update-children` step makes it straightforward to keep an Apache Brooklyn model +in synch with external resources, from a cloud, GitHub or Jira tickets, or any data source you choose. +The Brooklyn blueprint can then be used to attach management logic, including for example +automatically deploying branched resources into ephemeral test environments. + +This example shows how CloudFormation stacks in AWS can be synchronized. + +Firstly, we define our type to represent discovered stack and be able to refresh `on_update`: + +{% highlight yaml %} +{% readj aws-cfn-type.yaml %} +{% endhighlight %} + +This should be added to the catalog. + +We can then deploy our Brooklyn application to discover and monitor stacks: + +{% highlight yaml %} +{% readj aws-discoverer.yaml %} +{% endhighlight %} + +Create and delete stacks, and see them update in Brooklyn. +Then consider: + +* Modify the `ssh aws` step in the "discoverer" to filter based on your preferred tags. +* Use the `transform ... | merge` operator to combine lists from different regions. +* Add other policies to check for drift on stacks and show failures in AMP if there is drift. +* Create a similar workflow to monitor pull requests using the `gh` CLI; + then create, update, delete, and track ephemeral test deployments based on those diff --git a/guide/blueprints/workflow/examples/index.md b/guide/blueprints/workflow/examples/index.md index 3ea6c5ad..bc1ef878 100644 --- a/guide/blueprints/workflow/examples/index.md +++ b/guide/blueprints/workflow/examples/index.md @@ -6,6 +6,7 @@ children: - ansible-bash/ - git-latest/ - oauth/ +- aws-cfn-stacks/ --- The following examples are available: diff --git a/guide/blueprints/workflow/steps/steps.yaml b/guide/blueprints/workflow/steps/steps.yaml index 5c343695..a543ce1b 100644 --- a/guide/blueprints/workflow/steps/steps.yaml +++ b/guide/blueprints/workflow/steps/steps.yaml @@ -490,15 +490,15 @@ - name: update-children summary: Updates children of an entity to be in 1:1 correspondence with items in a given list - shorthand: '`update-children [of PARENT] type BLUEPRINT id IDENTIFIER from ITEMS`' + shorthand: '`update-children [of PARENT] type BLUEPRINT id IDENTIFIER_EXPRESSION from ITEMS`' input: | * `blueprint`: a blueprint or name of a registered entity type to use to create the children; this is required unless `on_create` is specified; where supplied as a blueprint (not a string) the variable `item` can be referenced to provide initial values, but note this is not updated - * `identifier`: an expression in terms of a local variable `item` to use to identify the same child; - e.g. if the `items` is of the form `[{ field_id: ticket1, name: "Ticket 1" },...]` then - and `identifier: ${item.field_id}` will create/update/delete a child whose ID is `ticket1`; - ignored unless `item_check_workflow` is specified + * `identifier_expression`: an expression in terms of a local variable `item` to use to identify the same child; + e.g. if the `items` is of the form `[{ field_id: 1, name: "Ticket 1" },...]` then + `identifier_expression: ticket_${item.field_id}` will create/update/delete a child whose ID is `ticket_1`; + used only by the default `match_check` so not required if that is overridden not to use it * `items`: the list of items to be used to create/update/delete the children * `parent`: the entity or entity ID whose children are to be updated, defaulting to the current entity; any children which do not match something in `items` may be removed @@ -526,31 +526,29 @@ this optionally supplied workflow allows the matching process to be customized, filtering and determining the intended child or its id; it will be invoked for each item in `items` to find a matching child/entity if one is already present; the workflow is passed input variable `item` (and other inputs to the `update-children` step) - and should return either the existing child that corresponds to it or the identifier for the child that should (but might or might not) exist, + and should return either the entity that corresponds to it which should be updated (`on_update`) or the identifier for the child that should be created, or `null` if the item should be omitted; - the default implementation of this workflow is to evaluate the expression in `identifier`, i.e. `let id = ${${identifier}}`, - then to return any child matching that if there is one or the identifier, i.e. `${parent.child[${id}]} ?? ${id}` + the default implementation is to evaluate the expression in `identifier`, i.e. `let id = ${${identifier}}`, + then to return any child matching that if there is one or the resolved identifier, i.e. `${parent.child[${id}]} ?? ${id}`; + this workflow may create or reparent an entity and return it, and it will not have `on_create` invoked * `creation_check`: this optionally supplied workflow allows filtering and custom creation; - it will be invoked for each item in `items` for which the `match_check` returned a non-null value, - the workflow is passed input variable `item`, the resulting `match` from the match check (and other inputs to the `update-children` step) - and has the same return semantics, with the difference that this method can create and return a custom entity; - - and if an entity is returned or created (i.e. this workflow does not return `false`) then `on_update` will be called; - the default implementation of this workflow is to return `true`; - this workflow may, for example, check whether an entity that exists elsewhere (e.g. something previously created then reparented away in the `deletion_check`) - should be reparented again under the `parent` and re-connected to this synchronization process + it will be invoked for each item in `items` for which the `match_check` returned a string value indicating to create a child, + the workflow is passed the resulting `match` and the `item` (and other inputs to the `update-children` step), + and should return the entity created or `null` if the item should be omitted; + the result of this, if not null, will have the `on_create` handler invoked on it; + the default implementation is to create the entity (applying the `resolve_expression` transform on `blueprint`), + set the ID, and return the newly created entity * `deletion_check`: this optionally supplied workflow allows customizing pre-deletion activities and/or the deletion itself; - it will be invoked for each pre-existing child which was not - returned by the `item_check_workflow`, + it will be invoked for each child of `parent` which was not returned by the `match_check` or `creation_check`, with each such entity passed as an input variable `child` (along with other inputs to the `update-children` step); it can then return `true` or `false` to specify whether the child should be deleted (with `on_delete` called prior to deletion if `true` is returned); this workflow may reparent the entity and return `false` if it is intended to keep the entity but - disconnected from this synchronization process, + disconnect it from this synchronization process, or may even `delete-entity ${child}` (although that is not usually necessary) output: the output from the previous step, or null if this is the first step