blob: 010f35cb5a81ccdec89d0bad194dd042eaeae7a8 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
brooklyn.catalog:
version: "1.2.0-SNAPSHOT" # BROOKLYN_VERSION
items:
- id: 1-server-template
itemType: template
name: "Template 1: Server"
description: |
Sample YAML to provision a server in a cloud with illustrative VM properties
item:
name: Server (Brooklyn Example)
# this basic example shows how Brooklyn can provision a single raw VM
# in the cloud or location of your choice
services:
- type: server
name: My VM
# location can be e.g. `softlayer` or `jclouds:openstack-nova:https://9.9.9.9:9999/v2.0/`,
# or `localhost` or `byon:(hosts="10.9.1.1,10.9.1.2,produser2@10.9.2.{10,11,20-29}")`
location:
jclouds:aws-ec2:
# edit these to use your credential (or delete if credentials specified in brooklyn.properties)
identity: <REPLACE>
credential: <REPLACE>
region: eu-central-1
# we want Ubuntu, with a lot of RAM
osFamily: ubuntu
minRam: 8gb
# set up this user and password (default is to authorize a public key)
user: sample
password: s4mpl3
- id: 2-bash-web-server-template
itemType: template
name: "Template 2: Bash Web Server"
description: |
Sample YAML building on Template 1,
adding bash commands to launch a Python-based web server
on port 8020
item:
name: Python Web Server (Brooklyn Example)
# this example builds on the previous one,
# adding some scripts to initialize the VM
services:
- type: vanilla-bash-server
name: My Bash Web Server VM
brooklyn.config:
install.command: |
# install python if not present
which python || \
{ sudo apt-get update && sudo apt-get install -y python ; } || \
{ sudo yum update && sudo yum install python ; } || \
{ echo WARNING: cannot install python && exit 1 ; }
customize.command: |
# create the web page to serve
cat > index.html << EOF
Hello world.
<p>
I am ${ENTITY_INFO}, ${MESSAGE:-a Brooklyn sample}.
<p>
Created at: `date`
<p>
I am running at ${HOSTNAME}, with on-box IP configuration:
<pre>
`ifconfig | grep inet`
</pre>
EOF
launch.command: |
# launch in background (ensuring no streams open), and record PID to file
nohup python -m SimpleHTTPServer ${PORT:-8020} < /dev/null > output.txt 2>&1 &
echo $! > ${PID_FILE:-pid.txt}
sleep 5
ps -p `cat ${PID_FILE:-pid.txt}`
if [ $? -ne 0 ] ; then
cat output.txt
echo WARNING: python web server not running
exit 1
fi
shell.env:
HOSTNAME: $brooklyn:attributeWhenReady("host.name")
PORT: $brooklyn:config("my.app.port")
ENTITY_INFO: $brooklyn:component("this", "")
MESSAGE: $brooklyn:config("my.message")
# custom
my.app.port: 8020
my.message: "good to meet you"
brooklyn.enrichers:
# publish the URL as a sensor; the GUI will pick this up (main.uri)
- type: org.apache.brooklyn.enricher.stock.Transformer
brooklyn.config:
uniqueTag: url-generator
enricher.sourceSensor: host.subnet.hostname
# use the definition from Attributes class, as it has a RendererHint so GUI makes it a link
enricher.targetSensor: $brooklyn:sensor("org.apache.brooklyn.core.entity.Attributes", "main.uri")
enricher.targetValue:
$brooklyn:formatString:
- "http://%s:%s/"
- $brooklyn:attributeWhenReady("host.subnet.hostname")
- $brooklyn:config("my.app.port")
location:
jclouds:aws-ec2:
region: eu-central-1
# edit these (or delete if credentials specified in brooklyn.properties)
identity: <REPLACE>
credential: <REPLACE>
- id: 3-bash-web-and-riak-template
itemType: template
name: "Template 3: Bash Web Server and Scaling Riak Cluster"
description: |
Sample YAML building on Template 2,
composing that blueprint with a Riak cluster and injecting the URL.
We recommend using CentOS or Debian as they both provide the required 'riak' package.
item:
name: Bash Web Server and Riak Cluster (Brooklyn Example)
# this example *references* the previous one,
# combining it with a stock blueprint for a Riak cluster,
# and shows how a sensor from the latter can be injected
services:
# reference template 2, overriding message to point at riak
- type: 2-bash-web-server-template
brooklyn.config:
my.message: $brooklyn:formatString("connected to Riak at %s",
$brooklyn:entity("riak-cluster").attributeWhenReady("main.uri"))
# and clear the location defined there so it is taken from this template
locations: []
# use the off-the-shelf Riak cluster
- type: org.apache.brooklyn.entity.nosql.riak.RiakCluster
id: riak-cluster
initialSize: 3
# and add a policy to scale based on ops per minute
brooklyn.policies:
- type: org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy
brooklyn.config:
metric: riak.node.ops.1m.perNode
# more than 100 ops per second (6k/min) scales out, less than 50 scales back
# up to a max of 8 riak nodes here (can be changed in GUI / REST API afterwards)
autoscaler.metricUpperBound: 6000
autoscaler.metricLowerBound: 3000
autoscaler.minPoolSize: 3
autoscaler.maxPoolSize: 8
autoscaler.resizeUpStabilizationDelay: 30s
autoscaler.resizeDownStabilizationDelay: 5m
location:
jclouds:aws-ec2:
region: eu-central-1
# edit these (or delete if credentials specified in brooklyn.properties)
identity: <REPLACE>
credential: <REPLACE>
- id: 4-resilient-bash-web-cluster-template
itemType: template
name: "Template 4: Resilient Load-Balanced Bash Web Cluster with Sensors"
description: |
Sample YAML to provision a cluster of the bash/python web server nodes,
with sensors configured, and a load balancer pointing at them,
and resilience policies for node replacement and scaling.
We recommend using CentOS or Debian as they both provide the required 'riak' package.
item:
name: Resilient Load-Balanced Bash Web Cluster (Brooklyn Example)
# this final example shows some of the advanced functionality:
# defining custom sensors, and a cluster with a "spec",
# policies for resilience and scaling based on that sensor,
# and wiring a load balancer in front of the cluster
# combining this with the riak cluster in the previous example
# is left as a suggested exercise for the user
services:
# define a cluster of the web nodes
- type: cluster
name: Cluster of Bash Web Nodes
id: my-web-cluster
brooklyn.config:
initialSize: 1
memberSpec:
$brooklyn:entitySpec:
# template 2 is used as the spec for items in this cluster
# with a new message overwriting the previous,
# and a lot of sensors defined
type: 2-bash-web-server-template
name: My Bash Web Server VM with Sensors
# and clear the location defined there so it is taken from this template
locations: []
brooklyn.config:
my.message: "part of the cluster"
brooklyn.initializers:
# make a simple request-count sensor, by counting the number of 200 responses in output.txt
- type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
brooklyn.config:
name: reqs.count
targetType: int
period: 5s
command: "cat output.txt | grep HTTP | grep 200 | wc | awk '{print $1}'"
# and publish the port as a sensor so the load-balancer can pick it up
- type: org.apache.brooklyn.core.sensor.StaticSensor
brooklyn.config:
name: app.port
targetType: int
static.value: $brooklyn:config("my.app.port")
brooklyn.enrichers:
# derive reqs.per_sec from reqs.count
- type: org.apache.brooklyn.enricher.stock.YamlTimeWeightedDeltaEnricher
brooklyn.config:
enricher.sourceSensor: reqs.count
enricher.targetSensor: reqs.per_sec
enricher.delta.period: 1s
# and take an average over 30s for reqs.per_sec into reqs.per_sec.windowed_30s
- type: org.apache.brooklyn.enricher.stock.YamlRollingTimeWindowMeanEnricher
brooklyn.config:
enricher.sourceSensor: reqs.per_sec
enricher.targetSensor: reqs.per_sec.windowed_30s
enricher.window.duration: 30s
# emit failure sensor if a failure connecting to the service is sustained for 30s
- type: org.apache.brooklyn.policy.ha.ServiceFailureDetector
brooklyn.config:
entityFailed.stabilizationDelay: 30s
brooklyn.policies:
# restart if a failure is detected (with a max of one restart in 2m, sensor will propagate otherwise)
- type: org.apache.brooklyn.policy.ha.ServiceRestarter
brooklyn.config:
failOnRecurringFailuresInThisDuration: 2m
# back at the cluster, create a total per-sec and some per-node average
brooklyn.enrichers:
- type: org.apache.brooklyn.enricher.stock.Aggregator
brooklyn.config:
enricher.sourceSensor: reqs.per_sec
enricher.targetSensor: reqs.per_sec
transformation: sum
- type: org.apache.brooklyn.enricher.stock.Aggregator
brooklyn.config:
enricher.sourceSensor: reqs.per_sec
enricher.targetSensor: reqs.per_sec.per_node
transformation: average
- type: org.apache.brooklyn.enricher.stock.Aggregator
brooklyn.config:
enricher.sourceSensor: reqs.per_sec.windowed_30s
enricher.targetSensor: reqs.per_sec.windowed_30s.per_node
transformation: average
brooklyn.policies:
# resilience: if a per-node restart policy fails,
# just throw that node away and create a new one
- type: org.apache.brooklyn.policy.ha.ServiceReplacer
# and scale based on reqs/sec
- type: org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy
brooklyn.config:
# scale based on reqs/sec (though in a real-world situation,
# reqs.per_sec.windowed_30s.per_node might be a better choice)
metric: reqs.per_sec.per_node
# really low numbers, so you can trigger a scale-out just by hitting reload a lot
autoscaler.metricUpperBound: 3
autoscaler.metricLowerBound: 1
# sustain 3 reqs/sec for 2s and it will scale out
autoscaler.resizeUpStabilizationDelay: 2s
# only scale down when sustained for 1m
autoscaler.resizeDownStabilizationDelay: 1m
autoscaler.maxPoolSize: 10
# and add a load-balancer pointing at the cluster
- type: load-balancer
id: load-bal
brooklyn.config:
# point this load balancer at the cluster, specifying port to forward to
loadbalancer.serverpool: $brooklyn:entity("my-web-cluster")
member.sensor.portNumber: app.port
# disable sticky sessions to allow easy validation of balancing via browser refresh
nginx.sticky: false
brooklyn.enrichers:
# publish a few useful info sensors and KPI's to the root of the app
- type: org.apache.brooklyn.enricher.stock.Propagator
brooklyn.config:
uniqueTag: propagate-load-balancer-url
producer: $brooklyn:entity("load-bal")
propagating:
- main.uri
- type: org.apache.brooklyn.enricher.stock.Propagator
brooklyn.config:
uniqueTag: propagate-reqs-per-sec
producer: $brooklyn:entity("my-web-cluster")
propagating:
- reqs.per_sec
- reqs.per_sec.windowed_30s.per_node
location:
jclouds:aws-ec2:
# edit these (or delete if credentials specified in brooklyn.properties)
identity: <REPLACE>
credential: <REPLACE>
region: eu-central-1
minRam: 2gb