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

Reply via email to