diff --git a/README.md b/README.md
index 3c0ec472..8cc871b6 100644
--- a/README.md
+++ b/README.md
@@ -14,12 +14,13 @@ repository. To install this, follow the instructions below.
Clocker for [Apache Brooklyn](https://brooklyn.apache.org/) is a set of open
source, Apache Licensed tools designed to make working with [Docker](https://www.docker.com/)
containers as simple as a few clicks. Clocker contains [Brooklyn blueprints](http://brooklyn.apache.org/v/latest/start/blueprints.html)
-to enable deployment and management of [Docker Swarm](https://www.docker.com/products/docker-swarm)
-and [Kubernetes](http://kubernetes.io/) clusters.
+to enable deployment and management of [Docker Swarm](https://www.docker.com/products/docker-swarm),
+[Amazon ECS](https://aws.amazon.com/ecs/) and [Kubernetes](http://kubernetes.io/) clusters.
You will find the source code for the blueprints in this repository.
* [Docker](./common/catalog/docker/)
+* [ECS](./ecs/src/main/resources/ecs/)
* [Swarm](./swarm/catalog/swarm/)
* [Kubernetes](./kubernetes/catalog/kubernetes/)
@@ -34,9 +35,11 @@ brooklyn.catalog:
brooklyn.libraries:
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.etcd&a=brooklyn-etcd&v=2.3.0-SNAPSHOT"
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-common&v=2.1.0-SNAPSHOT"
+ - "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-ecs&v=2.1.0-SNAPSHOT"
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-swarm&v=2.1.0-SNAPSHOT"
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-kubernetes&v=2.1.0-SNAPSHOT"
items:
+ - classpath://io.brooklyn.clocker.ecs:ecs/catalog.bom
- classpath://io.brooklyn.clocker.swarm:swarm/catalog.bom
- classpath://io.brooklyn.clocker.kubernetes:kubernetes/catalog.bom
```
@@ -47,6 +50,7 @@ You must add the following JARs to `./lib/dropins`:
* [brooklyn-etcd](https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.etcd&a=brooklyn-etcd&v=2.3.0-SNAPSHOT)
* [common](https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-common&v=2.1.0-SNAPSHOT)
+* [ecs](https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-ecs&v=2.1.0-SNAPSHOT)
* [swarm](https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-swarm&v=2.1.0-SNAPSHOT)
* [kubernetes](https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-kubernetes&v=2.1.0-SNAPSHOT)
@@ -55,6 +59,7 @@ Then add the catalog entries using the following YAML:
```YAML
brooklyn.catalog:
items:
+ - classpath://ecs/catalog.bom
- classpath://swarm/catalog.bom
- classpath://kubernetes/catalog.bom
```
diff --git a/clocker.bom b/clocker.bom
index 01ea8d16..1a6659cb 100644
--- a/clocker.bom
+++ b/clocker.bom
@@ -2,8 +2,10 @@ brooklyn.catalog:
brooklyn.libraries:
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.etcd&a=brooklyn-etcd&v=2.3.0-SNAPSHOT"
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-common&v=2.1.0-SNAPSHOT"
+ - "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-ecs&v=2.1.0-SNAPSHOT"
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-swarm&v=2.1.0-SNAPSHOT"
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-kubernetes&v=2.1.0-SNAPSHOT"
items:
+ - classpath://io.brooklyn.clocker.ecs:ecs/catalog.bom
- classpath://io.brooklyn.clocker.swarm:swarm/catalog.bom
- classpath://io.brooklyn.clocker.kubernetes:kubernetes/catalog.bom
diff --git a/common/catalog/docker/catalog.bom b/common/catalog/docker/catalog.bom
index fd3278cc..1a769786 100644
--- a/common/catalog/docker/catalog.bom
+++ b/common/catalog/docker/catalog.bom
@@ -1,13 +1,13 @@
brooklyn.catalog:
items:
- - classpath://io.brooklyn.clocker.common:docker/docker.bom
+ - classpath://io.brooklyn.clocker.common:docker/docker.bom
- - id: docker-engine-template
- name: "Docker Engine"
- description: |
- Creates a single docker engine.
- itemType: template
- iconUrl: classpath://io.brooklyn.clocker.common:icons/docker.png
- item:
- services:
- - type: docker-engine
\ No newline at end of file
+ - id: docker-engine-template
+ name: "Docker Engine"
+ description: |
+ Creates a single docker engine.
+ itemType: template
+ iconUrl: classpath://io.brooklyn.clocker.common:icons/docker.png
+ item:
+ services:
+ - type: docker-engine
diff --git a/ecs/catalog/ecs/catalog.bom b/ecs/catalog/ecs/catalog.bom
new file mode 100644
index 00000000..cddb229e
--- /dev/null
+++ b/ecs/catalog/ecs/catalog.bom
@@ -0,0 +1,4 @@
+brooklyn.catalog:
+ items:
+ - classpath://io.brooklyn.clocker.common:docker/catalog.bom
+ - classpath://io.brooklyn.clocker.ecs:ecs/ecs.bom
diff --git a/ecs/catalog/ecs/ecs.bom b/ecs/catalog/ecs/ecs.bom
new file mode 100644
index 00000000..d4bc3cee
--- /dev/null
+++ b/ecs/catalog/ecs/ecs.bom
@@ -0,0 +1,286 @@
+brooklyn.catalog:
+ version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
+ publish:
+ description: |
+ Resources for working with Docker and Amazon ECS from Apache Brooklyn
+ license_code: APACHE-2.0
+ overview: README.md
+
+ items:
+ - id: ecs-cluster-template
+ name: "EC2 Container Service Docker Cluster"
+ description: |
+ Creates a cluster of Docker engines for use with Amazon ECS
+ itemType: template
+ iconUrl: classpath://io.brooklyn.clocker.ecs:icons/ecs.png
+ item:
+ services:
+ - type: ecs-cluster
+
+ - id: ecs-cluster
+ name: "EC2 Container Service Docker Cluster"
+ description: |
+ Creates a cluster of Docker engines for use with Amazon ECS
+ itemType: entity
+ iconUrl: classpath://io.brooklyn.clocker.ecs:icons/ecs.png
+ item:
+ type: org.apache.brooklyn.entity.stock.BasicApplication
+
+ brooklyn.parameters:
+ # Duplicated parameters for UI visibility
+ - name: docker.initial.size
+ label: "Initial Cluster Size"
+ description: |
+ Size of the docker cluster when created initially
+ type: integer
+ default: 1
+ - name: docker.max.size
+ label: "Maximum Cluster Size"
+ description: |
+ Maximum size the docker cluster can be scaled to
+ type: integer
+ default: 5
+ - name: docker.sharedsecuritygroup.create
+ label: "Create Docker SharedSecurityGroup"
+ description: |
+ Clocker blueprint will configure security groups to allow access between docker nodes and
+ to allow external access to deployed apps
+ type: boolean
+ default: true
+ - name: ecs.cluster.name
+ label: "ECS Cluster Name"
+ description: |
+ The name of the ECS cluster
+ type: string
+ default: "clocker"
+
+ brooklyn.children:
+ - type: ecs-docker-cluster
+ id: ecs-docker-cluster
+ name: "ecs-docker-cluster"
+
+ - id: ecs-docker-cluster
+ name: "ECS Docker Cluster"
+ description: |
+ Creates a cluster of Docker engines, of configurable initial size, and
+ configures them for use with the Amazon EC2 comtainer service.
+ itemType: entity
+ item:
+ type: cluster
+
+ brooklyn.parameters:
+ - name: docker.initial.size
+ label: "Initial Cluster Size"
+ description: |
+ Size of the Docker cluster when created initially
+ type: integer
+ default: 1
+ - name: docker.max.size
+ label: "Maximum Cluster Size"
+ description: |
+ Maximum size the Docker cluster can be scaled to
+ type: integer
+ default: 5
+ - name: docker.scaling.cpu.limit
+ label: "Docker Scaling CPU Limit"
+ description: |
+ The average CPU usage limit for the Docker cluster, before another node
+ will automatically be added. The default is 0.95 or 95%
+ type: double
+ default: 0.95
+ - name: docker.recovery.quarantineFailedEntities
+ label: "Quarantine"
+ description: |
+ Quarantine failed entities instead of destroying them
+ type: boolean
+ default: true
+ - name: docker.recovery.failOnRecurringFailuresInThisDuration
+ label: "Fail Duration"
+ description: |
+ Reports entity as failed if it fails two or more times in this time window
+ type: long
+ default: 300000
+
+ brooklyn.policies:
+ - type: org.apache.brooklyn.policy.ha.ServiceReplacer
+ brooklyn.config:
+ failureSensorToMonitor: $brooklyn:sensor("ha.entityFailed")
+ failOnRecurringFailuresInThisDuration:
+ $brooklyn:config("docker.recovery.failOnRecurringFailuresInThisDuration")
+ - type: org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy
+ brooklyn.config:
+ autoscaler.metric:
+ $brooklyn:sensor("org.apache.brooklyn.entity.machine.MachineAttributes", "cpu.average")
+ autoscaler.metricLowerBound: 0.00
+ autoscaler.metricUpperBound:
+ $brooklyn:config("docker.scaling.cpu.limit")
+ autoscaler.minPoolSize:
+ $brooklyn:config("docker.initial.size")
+ autoscaler.maxPoolSize:
+ $brooklyn:config("docker.max.size")
+ autoscaler.resizeUpStabilizationDelay: 30s
+ autoscaler.resizeDownIterationMax: 0 # Disable scaling down
+
+ brooklyn.enrichers:
+ - type: org.apache.brooklyn.enricher.stock.Aggregator
+ brooklyn.config:
+ uniqueTag: ecs-docker-cluster-cpu-averageing
+ enricher.sourceSensor:
+ $brooklyn:sensor("org.apache.brooklyn.entity.machine.MachineAttributes", "machine.cpu")
+ enricher.targetSensor:
+ $brooklyn:sensor("org.apache.brooklyn.entity.machine.MachineAttributes", "cpu.average")
+ enricher.aggregating.fromMembers: true
+ transformation: average
+ - type: org.apache.brooklyn.enricher.stock.Aggregator
+ brooklyn.config:
+ uniqueTag: ecs-docker-cluster-tasks-total
+ enricher.sourceSensor: $brooklyn:sensor("ecs.tasks.count")
+ enricher.targetSensor: $brooklyn:sensor("ecs.tasks.total")
+ enricher.aggregating.fromMembers: true
+ transformation: sum
+
+ brooklyn.config:
+ cluster.initial.size: $brooklyn:config("docker.initial.size")
+ dynamiccluster.quarantineFailedEntities:
+ $brooklyn:config("docker.recovery.quarantineFailedEntities")
+ dynamiccluster.memberspec:
+ $brooklyn:entitySpec:
+ type: docker-engine-with-ecs
+ id: docker-engine
+ name: "docker-engine"
+
+ - id: docker-engine-with-ecs
+ name: Docker Engine with ECS
+ description: |
+ A docker-engine customised with the ECS agent
+ itemType: entity
+ iconUrl: classpath://io.brooklyn.clocker.common:icons/docker.png
+ item:
+ type: docker-engine
+
+ brooklyn.parameters:
+ - name: docker.recovery.stabilizationDelay
+ label: "Stabilization Delay"
+ description: |
+ Time period for which the service must be consistently in the same state to trigger an action.
+ Should be long enough that restart will not trigger failure.
+ type: org.apache.brooklyn.util.time.Duration
+ default: 5m
+
+ brooklyn.enrichers:
+ - type: org.apache.brooklyn.policy.ha.ServiceFailureDetector
+ brooklyn.config:
+ serviceOnFire.stabilizationDelay:
+ $brooklyn:config("docker.recovery.stabilizationDelay")
+ entityFailed.stabilizationDelay:
+ $brooklyn:config("docker.recovery.stabilizationDelay")
+ entityRecovered.stabilizationDelay:
+ $brooklyn:config("docker.recovery.stabilizationDelay")
+ - type: org.apache.brooklyn.enricher.stock.Propagator
+ brooklyn.config:
+ uniqueTag: ecs-agent-tasks-propagator
+ producer: $brooklyn:child("ecs-agent")
+ propagating:
+ - $brooklyn:sensor("ecs.tasks.count")
+
+ brooklyn.config:
+ provisioning.properties:
+ customizer:
+ $brooklyn:object:
+ type: org.apache.brooklyn.location.jclouds.networking.SharedLocationSecurityGroupCustomizer
+ object.fields:
+ tcpPortRanges:
+ - "32768-65535"
+ enabled: $brooklyn:config("docker.sharedsecuritygroup.create")
+
+ brooklyn.children:
+ - type: ecs-agent
+ id: ecs-agent
+ name: "ecs-agent"
+
+ - id: ecs-agent
+ name: "ECS Agent"
+ description: |
+ The ECS agent Docker container
+ itemType: entity
+ iconUrl: classpath://io.brooklyn.clocker.ecs:icons/ecs.png
+ item:
+ type: child-software-process
+
+ brooklyn.parameters:
+ - name: ecs.agent.version
+ label: "ECS Agent Version"
+ type: string
+ default: "1.13.0"
+ - name: ecs.cluster.name
+ label: "ECS Cluster Name"
+ description: |
+ The name of the ECS cluster
+ type: string
+ default: "clocker"
+
+ brooklyn.config:
+ shell.env:
+ ECS_AGENT_VERSION: $brooklyn:config("ecs.agent.version")
+ ECS_CLUSTER_NAME: $brooklyn:config("ecs.cluster.name")
+
+ install.command: |
+ sudo yum install -y jq
+ sudo mkdir -p /var/log/ecs
+ sudo mkdir -p /var/lib/ecs/data
+ sudo sysctl -w net.ipv4.conf.all.route_localnet=1
+ sudo iptables -t nat -A PREROUTING \
+ -p tcp -d 169.254.170.2 --dport 80 \
+ -j DNAT --to-destination 127.0.0.1:51679
+ sudo iptables -t nat -A OUTPUT \
+ -d 169.254.170.2 -p tcp -m tcp \
+ --dport 80 -j REDIRECT --to-ports 51679
+
+ launch.command: |
+ docker run --name ecs-agent \
+ --detach=true \
+ --restart=on-failure:10 \
+ --volume=/var/run/docker.sock:/var/run/docker.sock \
+ --volume=/var/log/ecs/:/log \
+ --volume=/var/lib/ecs/data:/data \
+ --net=host \
+ --env=ECS_LOGFILE=/log/ecs-agent.log \
+ --env=ECS_LOGLEVEL=info \
+ --env=ECS_DATADIR=/data \
+ --env=ECS_CLUSTER=${ECS_CLUSTER_NAME} \
+ --env=ECS_ENABLE_TASK_IAM_ROLE=true \
+ --env=ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=true \
+ amazon/amazon-ecs-agent:v${ECS_AGENT_VERSION}
+
+ checkRunning.command: |
+ [[ $(docker inspect --format "{{ .State.Running }}" ecs-agent) == "true" ]]
+
+ brooklyn.initializers:
+ - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
+ brooklyn.config:
+ name: ecs.agent.version
+ description: |
+ ECS installed version details
+ targetType: string
+ command: |
+ curl http://localhost:51678/v1/metadata |
+ jq '.Version'
+ - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
+ brooklyn.config:
+ name: ecs.instance.arn
+ description: |
+ ECS instance ARN identifier
+ targetType: string
+ command: |
+ curl http://localhost:51678/v1/metadata |
+ jq '.ContainerInstanceArn'
+ - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
+ brooklyn.config:
+ name: ecs.tasks.count
+ description: |
+ ECS task count for the instance
+ targetType: integer
+ command: |
+ curl http://localhost:51678/v1/tasks |
+ jq '.Tasks[] | .Arn' ~/tmp/ecs/tasks.json |
+ wc -l
diff --git a/ecs/examples/ecs-cluster.yaml b/ecs/examples/ecs-cluster.yaml
new file mode 100644
index 00000000..ade3f3ce
--- /dev/null
+++ b/ecs/examples/ecs-cluster.yaml
@@ -0,0 +1,33 @@
+id: ecs-cluster
+name: "Amazon ECS Docker Cluster"
+description: |
+ Creates a cluster of Docker Engines with the Amazon ECS Agent.
+
+ Deploys on AWS using the configuread IAM profile set in 'templateOptions'
+ for the instances. See the ECS documentation for detailed instructions:
+
+ http://docs.aws.amazon.com/AmazonECS/latest/developerguide/instance_IAM_role.html
+
+location:
+ jclouds:aws-ec2:
+ region: eu-west-1
+ privateKeyFile: "~/.ssh/ecs.pem"
+ loginUser.privateKeyFile: "~/.ssh/ecs.pem"
+ keyPair: "ecs"
+ templateOptions:
+ iamInstanceProfileArn:
+ "arn:aws:iam::12345678:instance-profile/clocker"
+ securityGroups:
+ - "sg-xxxxxx"
+
+services:
+ - type: ecs-cluster
+ name: "ecs-cluster"
+ brooklyn.config:
+ ecs.cluster.name: "clocker"
+ docker.initial.size: 2
+ docker.max.size: 5
+ docker.sharedsecuritygroup.create: true
+ provisioning.properties:
+ minRam: 10g
+ minCores: 4
diff --git a/ecs/pom.xml b/ecs/pom.xml
new file mode 100644
index 00000000..ea394bfb
--- /dev/null
+++ b/ecs/pom.xml
@@ -0,0 +1,60 @@
+
+
+ 4.0.0
+
+
+ io.brooklyn.clocker
+ clocker-parent
+ 2.1.0-SNAPSHOT
+
+
+ Clocker :: ECS
+ clocker-ecs
+ jar
+
+
+
+
+ catalog
+ false
+
+
+ resources
+ false
+
+
+ tests
+ false
+ tests
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ 1.12
+
+
+ attach-artifact
+ package
+
+ attach-artifact
+
+
+
+
+ ${project.basedir}/catalog/ecs/ecs.bom
+ bom
+ ecs
+
+
+
+
+
+
+
+
+
diff --git a/ecs/resources/icons/ecs.png b/ecs/resources/icons/ecs.png
new file mode 100644
index 00000000..066088a9
Binary files /dev/null and b/ecs/resources/icons/ecs.png differ
diff --git a/ecs/tests/ecs/ecs.tests.bom b/ecs/tests/ecs/ecs.tests.bom
new file mode 100644
index 00000000..01948b07
--- /dev/null
+++ b/ecs/tests/ecs/ecs.tests.bom
@@ -0,0 +1,84 @@
+brooklyn.catalog:
+ version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
+ iconUrl: https://raw.githubusercontent.com/docker-library/docs/471fa6e4cb58062ccbf91afc111980f9c7004981/swarm/logo.png
+ dependsOn:
+ - tests/common.tests.bom
+ - tests/docker.tests.bom
+ license_code: APACHE-2.0
+
+# NOTE This test requires a location in an Amazon EC2 region that has had an
+# ECS cluster created already, named 'clocker-qa-test' and an IAM profile
+# to access it also named 'clocker-qa-test' as in the following YAML fragment:
+#
+# location:
+# jclouds:aws-ec2:
+# region: eu-west-1
+# templateOptions:
+# iamInstanceProfileName: "clocker-qa-test"
+
+ items:
+ - id: ecs-cluster-tests
+ name: "ECS Cluster Tests"
+ description: |
+ Tests on the ECS cluster of Docker Engine entities
+ itemType: entity
+ item:
+ type: test-case
+ name: "ecs-cluster-tests"
+
+ brooklyn.config:
+ docker.initial.size: 2
+ docker.max.size: 3
+ docker.scaling.cpu.limit: 0.95
+ docker.recovery.stabilizationDelay: 10s
+ docker.recovery.failOnRecurringFailuresInThisDuration: 5m
+
+ brooklyn.children:
+ - type: ecs-cluster
+ id: ecs-cluster
+ name: "ecs-cluster"
+ description: |
+ The ECS cluster to test
+ brooklyn.config:
+ ecs.cluster.name: "clocker-qa-test"
+ ecs.agent.version: "1.13.0"
+
+ - type: test-case
+ name: "ecs-test-suite"
+ brooklyn.children:
+ - type: test-case
+ name: "GROUP-1 Test ECS entity"
+ brooklyn.config:
+ targetId: ecs-cluster
+ brooklyn.children:
+ - type: assert-up
+ name: "TEST-01 Assert up"
+ - type: assert-running
+ name: "TEST-02 Assert running"
+ - type: sensor-test
+ name: "TEST-03 Size of cluster is 2"
+ targetId: ecs-docker-cluster
+ timeout: 20m
+ sensor: group.members.count
+ assert:
+ equals: $brooklyn:config("docker.initial.size")
+ - type: sensor-test
+ name: "TEST-04 Number of tasks is 0"
+ targetId: ecs-docker-cluster
+ timeout: 20m
+ sensor: ecs.tasks.total
+ assert:
+ equals: 0
+ - type: loop-test-case
+ name: "TEST-05 Check agent version"
+ brooklyn.config:
+ targetId: ecs-docker-cluster
+ test.spec:
+ $brooklyn:entitySpec:
+ type: sensor-test
+ name: "TEST-05-a Agent version sensor same as config"
+ targetId: ecs-agent
+ timeout: 20m
+ sensor: ecs.agent.versoin
+ assert:
+ contains: $brooklyn:config("ecs.agent.version")
diff --git a/ecs/tests/ecs/tests.bom b/ecs/tests/ecs/tests.bom
new file mode 100644
index 00000000..181e9153
--- /dev/null
+++ b/ecs/tests/ecs/tests.bom
@@ -0,0 +1,21 @@
+brooklyn.catalog:
+ version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
+ iconUrl: https://raw.githubusercontent.com/docker-library/docs/471fa6e4cb58062ccbf91afc111980f9c7004981/swarm/logo.png
+ dependsOn:
+ - tests/ecs.tests.bom
+ license_code: APACHE-2.0
+
+ items:
+ - id: ecs-tests
+ name: "ECS Tests"
+ description: |
+ Tests for ECS entities
+ itemType: template
+ item:
+ brooklyn.config:
+ timeout: 1h
+ timeout.initialStartup: 1h
+ timeout.runtimeAssertion: 1h
+
+ services:
+ - type: ecs-cluster-tests
diff --git a/pom.xml b/pom.xml
index 98c1f6c8..00abd97c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,6 +30,7 @@
common
+ ecs
swarm
kubernetes
feature