├── aws └── ecs │ ├── README.md │ ├── packer │ ├── to-upload │ │ ├── scope.conf │ │ ├── weave.conf │ │ ├── ecs.override │ │ ├── peers.sh │ │ └── run.sh │ ├── template.json │ └── build-all-amis.sh │ ├── CHANGELOG.md │ ├── cloudformation-no-app.json │ ├── cloudformation.json │ ├── cloudformation-larger-app.json │ └── cloudformation-identiorca.json ├── README.md ├── .travis.yml └── LICENSE /aws/ecs/README.md: -------------------------------------------------------------------------------- 1 | 4 | # Weave's ECS AMIs 5 | 6 | You will find the documentation at the [Scope website](https://www.weave.works/docs/scope/latest/ami/) 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Weave Third-Party Integrations 2 | 3 | This repository only includes the [integration with AWS's ECS](aws/ecs/) for now. 4 | 5 | ## Getting Help 6 | 7 | If you have any questions about, feedback for or problems with `integrations`: 8 | 9 | - Invite yourself to the Weave Users Slack. 10 | - Ask a question on the [#general](https://weave-community.slack.com/messages/general/) slack channel. 11 | - [File an issue](https://github.com/weaveworks/integrations/issues/new). 12 | 13 | Weaveworks follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a Weaveworks project maintainer, or Alexis Richardson (alexis@weave.works). 14 | 15 | Your feedback is always welcome! 16 | -------------------------------------------------------------------------------- /aws/ecs/packer/to-upload/scope.conf: -------------------------------------------------------------------------------- 1 | # Copyright 2014-2015 Weaveworks. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the 4 | # "License"). You may not use this file except in compliance 5 | # with the License. A copy of the License is located at 6 | # 7 | # http://aws.amazon.com/apache2.0/ 8 | # 9 | # or in the "license" file accompanying this file. This file is 10 | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | # CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | description "Weave Scope Service init" 16 | author "Weaveworks" 17 | start on stopped rc RUNLEVEL=[345] 18 | 19 | # respawn the job up to 10 times within a minute 20 | # If the job exceeds these values, it will be stopped and 21 | # marked as failed. 22 | respawn 23 | respawn limit 10 60 24 | 25 | exec /etc/weave/run.sh scope 26 | 27 | pre-stop exec scope stop 28 | -------------------------------------------------------------------------------- /aws/ecs/packer/to-upload/weave.conf: -------------------------------------------------------------------------------- 1 | # Copyright 2014-2015 Weaveworks. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the 4 | # "License"). You may not use this file except in compliance 5 | # with the License. A copy of the License is located at 6 | # 7 | # http://aws.amazon.com/apache2.0/ 8 | # 9 | # or in the "license" file accompanying this file. This file is 10 | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | # CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | description "Weave Service init" 16 | author "Weaveworks" 17 | # Make sure weave starts either when after the system-v init scripts are 18 | # finished (rc Upstart task is done) or ecs is started independently 19 | # (e.g. ecs/docker upgrades) 20 | start on (stopped rc RUNLEVEL=[345] or starting ecs) 21 | 22 | # respawn the job up to 10 times within a minute 23 | # If the job exceeds these values, it will be stopped and 24 | # marked as failed. 25 | respawn 26 | respawn limit 10 60 27 | 28 | exec /etc/weave/run.sh weave 29 | -------------------------------------------------------------------------------- /aws/ecs/packer/to-upload/ecs.override: -------------------------------------------------------------------------------- 1 | # Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the 4 | # "License"). You may not use this file except in compliance 5 | # with the License. A copy of the License is located at 6 | # 7 | # http://aws.amazon.com/apache2.0/ 8 | # 9 | # or in the "license" file accompanying this file. This file is 10 | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | # CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | start on started weave 16 | stop on stopping weave 17 | 18 | env DOCKER_HOST=unix:///var/run/weave/weave.sock 19 | 20 | pre-start script 21 | # Wait for weave container to be ready (for a maximum of two minutes to avoid an 22 | # Upstart deadlock if Weave failed to start). 23 | # This checks that the container is running but also implicitly checks that it's ready to 24 | # receive requests since DOCKER_HOST=unix:///var/run/weave/weave.sock 25 | timeout 120 bash -c 'while [ "$(docker inspect -f '"'"'{{.State.Running}}'"'"' weave 2> /dev/null )" != true ]; do sleep 1; done' || { stop ; exit 0; } 26 | exec /usr/libexec/amazon-ecs-init pre-start 27 | end script 28 | -------------------------------------------------------------------------------- /aws/ecs/packer/to-upload/peers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | # This script prints the list of Weave peers (IPs) of the EC2 instance executing the script. 4 | # The peers are identified as follows: 5 | # If the current instance is tagged with weave:peerGroupName=VALUE -> all other instances tagged as weave:peerGroupName=VALUE 6 | # Otherwise, all the other instances in the same Autoscaling Group (default) 7 | 8 | aws=/usr/local/bin/aws 9 | 10 | 11 | export AWS_DEFAULT_REGION=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region) 12 | current_instance_id=$(curl -s http://169.254.169.254/latest/meta-data/instance-id) 13 | 14 | PEER_GROUP_NAME=$($aws ec2 describe-instances --instance-ids $current_instance_id --query 'Reservations[0].Instances[0].Tags[?Key==`weave:peerGroupName`].Value' --output text) 15 | 16 | if [ -n "$PEER_GROUP_NAME" ]; then 17 | peer_instances=$($aws ec2 describe-tags --filters "Name=resource-type,Values=instance" "Name=tag:weave:peerGroupName,Values=$PEER_GROUP_NAME" --query "Tags[?ResourceId!=\`$current_instance_id\`].ResourceId" --output text) 18 | 19 | else 20 | current_autoscaling_group=$($aws autoscaling describe-auto-scaling-instances --query "AutoScalingInstances[?InstanceId==\`$current_instance_id\`].AutoScalingGroupName" --output text) 21 | 22 | if [ -z "$current_autoscaling_group" ]; then 23 | >&2 echo "instance doesn't belong to an autoscaling group" 24 | exit 1 25 | fi 26 | 27 | peer_instances=$($aws autoscaling describe-auto-scaling-instances --query "AutoScalingInstances[? AutoScalingGroupName==\`$current_autoscaling_group\` && InstanceId!=\`$current_instance_id\`].InstanceId" --output text) 28 | fi 29 | 30 | 31 | if [ -z "$peer_instances" ]; then 32 | # no peers found 33 | exit 0 34 | fi 35 | 36 | peer_ips=$($aws ec2 describe-instances --instance-ids $peer_instances --query 'Reservations[].Instances[].NetworkInterfaces[].PrivateIpAddress' --output text) 37 | echo $peer_ips 38 | 39 | -------------------------------------------------------------------------------- /aws/ecs/packer/to-upload/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eu 4 | 5 | LOGGER_TAG="" 6 | 7 | is_container_running() { 8 | [ "$(docker inspect -f '{{.State.Running}}' $1 2> /dev/null)" = true ] 9 | } 10 | 11 | succeed_or_die() { 12 | if ! OUT=$("$@" 2>&1); then 13 | echo "error: '$@' failed: $OUT" | logger -p local0.error -t $LOGGER_TAG 14 | exit 1 15 | fi 16 | echo $OUT 17 | } 18 | 19 | run_scope() { 20 | while true; do 21 | # verify that scope is not running 22 | while is_container_running weavescope; do sleep 2; done 23 | 24 | # launch scope 25 | ARGS="--probe.ecs=true" 26 | if [ -e /etc/weave/scope.config ]; then 27 | . /etc/weave/scope.config 28 | fi 29 | if [ -n "${SERVICE_TOKEN+x}" ]; then 30 | ARGS="$ARGS --service-token=$SERVICE_TOKEN" 31 | fi 32 | succeed_or_die scope launch $ARGS 33 | done 34 | } 35 | 36 | run_weave() { 37 | # Ideally we would use a pre-stop Upstart stanza for terminating Weave, but we can't 38 | # because it would cause ECS to stop in an unorderly manner: 39 | # 40 | # Stop Weave -> Weave pre-stop stanza -> Weave stopping event -> ECS pre-stop ... 41 | # 42 | # The Weave pre-stop stanza would kick in before stopping ECS, which would result in 43 | # the ECS Upstart job supervisor dying early (it talks to the weave proxy, 44 | # which is gone), not allowing the ECS pre-stop stanza to kick in and stop the 45 | # ecs-agent 46 | trap 'succeed_or_die weave stop; exit 0' TERM 47 | while true; do 48 | # verify that weave is not running 49 | while is_container_running weave; do sleep 2; done 50 | # launch weave 51 | PEERS=$(succeed_or_die /etc/weave/peers.sh) 52 | succeed_or_die weave launch --plugin=false --hostname-from-label 'com.amazonaws.ecs.container-name' $PEERS 53 | done 54 | } 55 | 56 | case $1 in 57 | weave) 58 | LOGGER_TAG="weave_runner" 59 | run_weave 60 | ;; 61 | scope) 62 | LOGGER_TAG="weave_scope_runner" 63 | run_scope 64 | ;; 65 | esac 66 | -------------------------------------------------------------------------------- /aws/ecs/packer/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": { 3 | "aws_access_key": "", 4 | "aws_secret_key": "", 5 | "aws_region": "", 6 | "source_ami": "", 7 | "ami_groups": "" 8 | }, 9 | "builders": [{ 10 | "type": "amazon-ebs", 11 | "region": "{{user `aws_region`}}", 12 | "source_ami": "{{user `source_ami`}}", 13 | "instance_type": "t2.micro", 14 | "ami_name": "Weaveworks ECS Image ({{isotime \"2006-01-02\"}})", 15 | "ami_groups": "{{user `ami_groups`}}", 16 | "communicator": "ssh", 17 | "ssh_username": "ec2-user", 18 | "ssh_file_transfer_method": "sftp", 19 | "ssh_pty": true 20 | }], 21 | 22 | "provisioners": [{ 23 | "type": "file", 24 | "source": "to-upload/ecs.override", 25 | "destination": "/home/ec2-user/ecs.override" 26 | }, { 27 | "type": "file", 28 | "source": "to-upload/weave.conf", 29 | "destination": "/home/ec2-user/weave.conf" 30 | }, { 31 | "type": "file", 32 | "source": "to-upload/scope.conf", 33 | "destination": "/home/ec2-user/scope.conf" 34 | }, { 35 | "type": "file", 36 | "source": "to-upload/peers.sh", 37 | "destination": "/home/ec2-user/peers.sh" 38 | }, { 39 | "type": "file", 40 | "source": "to-upload/run.sh", 41 | "destination": "/home/ec2-user/run.sh" 42 | }, { 43 | "type": "shell", 44 | "inline": [ 45 | "sudo yum -y update # make sure we provide the latest packages", 46 | 47 | "sudo yum -y install python-pip jq", 48 | "sudo python-pip install awscli", 49 | 50 | "sudo curl -L https://github.com/weaveworks/weave/releases/download/v2.3.0/weave -o /usr/local/bin/weave", 51 | "sudo chmod +x /usr/local/bin/weave", 52 | "sudo /usr/local/bin/weave setup", 53 | 54 | "sudo curl -L https://github.com/weaveworks/scope/releases/download/v1.9.0/scope -o /usr/local/bin/scope", 55 | "sudo chmod +x /usr/local/bin/scope", 56 | "docker pull weaveworks/scope:1.9.0", 57 | 58 | 59 | "sudo mv /home/ec2-user/weave.conf /etc/init/weave.conf", 60 | "sudo mv /home/ec2-user/scope.conf /etc/init/scope.conf", 61 | "sudo mv /home/ec2-user/ecs.override /etc/init/ecs.override", 62 | 63 | "sudo mkdir /etc/weave", 64 | "sudo mv /home/ec2-user/peers.sh /etc/weave/peers.sh", 65 | "sudo chmod +x /etc/weave/peers.sh", 66 | "sudo mv /home/ec2-user/run.sh /etc/weave/run.sh", 67 | "sudo chmod +x /etc/weave/run.sh", 68 | 69 | "# Remove all ECS execution traces added while running packer", 70 | "sudo stop ecs || true", 71 | "sudo docker rm ecs-agent 2> /dev/null || true", 72 | "sudo rm -rf /var/log/ecs/* /var/lib/ecs/data/*", 73 | "sudo rm /root/.ssh/authorized_keys", 74 | "sudo rm /home/ec2-user/.ssh/authorized_keys" 75 | ] 76 | }] 77 | 78 | } 79 | -------------------------------------------------------------------------------- /aws/ecs/packer/build-all-amis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z "${AWS_ACCESS_KEY_ID+x}" -a -z "${AWS_SECRET_ACCESS_KEY+x}" ]; then 4 | echo "error: both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY needs to be set" 5 | echo "usage: AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY $0" 6 | exit 1 7 | fi 8 | 9 | # Taken from http://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_container_instance.html 10 | BASE_AMIS=('us-east-1:ami-9eb4b1e5' 11 | 'us-east-2:ami-1c002379' 12 | 'us-west-1:ami-4a2c192a' 13 | 'us-west-2:ami-1d668865' 14 | 'eu-west-1:ami-8fcc32f6' 15 | 'eu-west-2:ami-cb1101af' 16 | 'eu-central-1:ami-0460cb6b' 17 | 'ap-northeast-1:ami-b743bed1' 18 | 'ap-southeast-1:ami-9d1f7efe' 19 | 'ap-southeast-2:ami-c1a6bda2' 20 | 'ca-central-1:ami-b677c9d2' 21 | ) 22 | 23 | # Mimic associative arrays using ":" to compose keys and values, 24 | # to make them work in bash v3 25 | function key(){ 26 | echo ${1%%:*} 27 | } 28 | 29 | function value(){ 30 | echo ${1#*:} 31 | } 32 | 33 | # Access is O(N) but .. we are mimicking maps with arrays 34 | function get(){ 35 | KEY=$1 36 | shift 37 | for I in $@; do 38 | if [ $(key $I) = "$KEY" ]; then 39 | echo $(value $I) 40 | return 41 | fi 42 | done 43 | } 44 | 45 | REGIONS="" 46 | for I in ${BASE_AMIS[@]}; do 47 | REGIONS="$REGIONS $(key $I)" 48 | done 49 | 50 | if [ -z "$(which packer)" ]; then 51 | echo "error: Cannot find Packer, please make sure it's installed" 52 | exit 1 53 | fi 54 | 55 | function invoke_packer() { 56 | LOGFILE=$(mktemp /tmp/${1}-packer-log-weave-ecs-XXXX) 57 | AMI_GROUPS="" 58 | if [ -n "${RELEASE+x}" ]; then 59 | AMI_GROUPS="all" 60 | fi 61 | packer build -var "ami_groups=${AMI_GROUPS}" -var "aws_region=$1" -var "source_ami=$2" template.json > $LOGFILE 62 | if [ "$?" = 0 ]; then 63 | echo "Success: $(tail -n 1 $LOGFILE)" 64 | rm $LOGFILE 65 | else 66 | echo "Failure: $1: see $LOGFILE for details" 67 | fi 68 | } 69 | 70 | BUILD_FOR_REGIONS="" 71 | if [ -n "${ONLY_REGION+x}" ]; then 72 | if [ -z "$(get $ONLY_REGION ${BASE_AMIS[@]})" ]; then 73 | echo "error: ONLY_REGION set to '$ONLY_REGION', which doesn't offer ECS yet, please set it to one from: ${REGIONS}" 74 | exit 1 75 | fi 76 | BUILD_FOR_REGIONS="$ONLY_REGION" 77 | else 78 | BUILD_FOR_REGIONS="$REGIONS" 79 | fi 80 | 81 | echo 82 | echo "Spawning parallel packer builds" 83 | echo 84 | 85 | 86 | 87 | for REGION in $BUILD_FOR_REGIONS; do 88 | AMI=$(get $REGION ${BASE_AMIS[@]}) 89 | echo Spawning AMI build for region $REGION based on AMI $AMI 90 | invoke_packer "${REGION}" "${AMI}" & 91 | done 92 | 93 | echo 94 | echo "Waiting for builds to finish, this will take a few minutes, please be patient" 95 | echo 96 | 97 | wait 98 | 99 | echo 100 | echo "Done" 101 | echo 102 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | env: 4 | global: 5 | - PATH="${PATH}:${HOME}/.local/bin" AWS_DEFAULT_REGION="eu-central-1" 6 | - secure: aEub6462B0FB31SUF/1GeM/qsi0eJ6xN6mRRb43Q7iUvzA2Mn/km7V9endU9m5LrxzC32FCNOXfwSasvHMCCOTrDChLBRoT/gR07iWbPCl/a8Ku9yyl13RVZfax1Wtulo3Ugb5T6bTN/WMOLCXwuLJGjE1PYRT134e/K42mQ7Tm1gTiMk1j4O7F9Bfa6znKsT+2ebz1Qy2qWXGubwsgpLLy7ZPgpANJ95L/HCZcs02wYWoqyUrH6X8D9vJ0PWx3szPEWCQd/nigILoPt9DinYCLg3qojQgX69dRezGK1TAd81Q4o7WzE7M6ySoIlpapfExUSKXLE1K+lRj69tkpvgNjo46tQGsbwLVoQXKgzjgHxT8zvnBSL76FQQMIsHoVmFsJH5QVGB8pktZSwsXcRqG8ROV0pI204/IX0zNB02STXB0rVMdjSuL6eVrIQ7dBPzOW25yIA564Q3URSAra8/RwDJidouJWWawZnQ61abXjKroWiOAarmAYWAr5730wwDRnPKzKMndy5tLF7xfsh+VPulhXdprZtjG1ga0VoGqTrncjcBEOZU7KRzGb0+brNllhMlVIi6xDbhoGKhXCcguwmAcucB1M5+9iT/V8AXEmAfKWOHH/MrruVctS0rry3yoLzJUYjC3lgVgJLNXbHKuns+k8zOHXs/5Em7rJVEq4= 7 | - secure: LsVGcTek2r9Geo5SbdyczufhdyGI10c9BABuu4KtBoP8qeSFiWUhDkDuLpVCrXCsb8YYDwFP1nUqW0s6vvBwujMLObjyFppVYwxqP/71yFXraIApYBnMcherhs7tVHYgSmgD3ANmGWA+dk847sio/otqu5ug+Q8KnAwYIl9Qca2mB5MMlI7mlh3F0s50tAdNaASKsNQ1/y+iytXzU1fnpYxOWTdiSduH5GJeRSD18ROUBGUPAZjTzAgBGPe2SniEX3TI+6C+5hYzXPpwNSJt5R2lB0aBTvt0j0SCaQ4pqp7caEe8TwI7OzWidJowYKK/C7oTD7aDoxgu6528+zuKgVRV8ABIWy/l4CDAPruw6WDStL5q53yfKle12Zq+48PK0hl3rmnL1yzgajtaLuEN1Z1B7MJRFcL1qC6Abw9DRrmbgPkpChFepMGIPWcEzETN075ddycLZCI58doP8Mf3Y26+UncmZPIAkFXBhZJK9jfnYutSPwN4kLoCGsYTDPfBuF9Xee2zuTQUqOhM+G2HYtmZfbnyY/3OwRobvDZvCnWngzR3m5O2Xap5io569gmvn5d5MHu9Qs/YjC5xuQCHfFK2SwZt5m04z+UaV77WNdIWsVY6PYGnGEoMSgIz1NlANU4XVpNNmQTaeikUFLuiAlilq8tEMCr38QlcPaFmlOU= 8 | 9 | install: 10 | - pip install --user awscli 11 | 12 | script: 13 | - set -o pipefail 14 | - aws cloudformation validate-template --template-body "file:////${PWD}/aws/ecs/cloudformation.json" | jq . 15 | - aws cloudformation validate-template --template-body "file:////${PWD}/aws/ecs/cloudformation-no-app.json" | jq . 16 | - aws cloudformation validate-template --template-body "file:////${PWD}/aws/ecs/cloudformation-larger-app.json" | jq . 17 | - aws cloudformation validate-template --template-body "file:////${PWD}/aws/ecs/cloudformation-identiorca.json" | jq . 18 | 19 | after_success: 20 | - mkdir cfn-to-publish 21 | - jq ".Description += \" (weaveworks/integrations@${TRAVIS_COMMIT})\"" "aws/ecs/cloudformation.json" > cfn-to-publish/ecs-baseline.json 22 | - jq ".Description += \" (weaveworks/integrations@${TRAVIS_COMMIT})\"" "aws/ecs/cloudformation-no-app.json" > cfn-to-publish/ecs-no-app.json 23 | - jq ".Description += \" (weaveworks/integrations@${TRAVIS_COMMIT})\"" "aws/ecs/cloudformation-larger-app.json" > cfn-to-publish/ecs-larger-app.json 24 | - jq ".Description += \" (weaveworks/integrations@${TRAVIS_COMMIT})\"" "aws/ecs/cloudformation-identiorca.json" > cfn-to-publish/ecs-identiorca.json 25 | 26 | deploy: 27 | provider: s3 28 | bucket: weaveworks-cfn-public 29 | skip_cleanup: true 30 | local_dir: cfn-to-publish 31 | upload_dir: integrations 32 | acl: public_read 33 | on: 34 | branch: master 35 | access_key_id: 36 | secure: iVRdq/jeQ6hHNDjn4tiyvKnMZpntoGECAKKKh7Tnhbti6jdPvgAamiFocorFIScEz7SLGPN1xDHg04LQNpjJaJ2fsw5lb/J8QYZ/RxVmi7gKP7MatLJ1yFfCnQZF8/oEkPkQK3s18siL3Qkv9wuwuqnJIGNbVYWHuBdFPri1HPVKdr6XDyQiDq5CESMruuAGp2DxCfkWNk8svtiQooKNrDS7WI4AYqjIO7vr/vHSssaIe6WkE7ibajkIeL3mAPYmLhgFcsXtvPv9oy/egyHdLuzsglgqZ1aA/6+UwgM9zZY7adnWYFy2CXZedQCQOUqZegaKEkgYPEDykRaioUWUCMKv/7HovyZ9SffMzvGo3xNIgktk0ItZS0PU2ZfWGVfsGrrwrU+JT0192p3176I6dnXW+fbkW8NO+2n9Xx5m5kz69MFU7JRgbFSmjY0/J+ZRc5YD03sEwo4kekhs2NwV4KRES0X6rd9XPWjSyQhXPdDwmZAHjLjRzr4J5gdu9uQxS1PGgSMyIHvhc6H7YNIbMIdT4QWkcObcK8gU+KKGT/RlbArUHskgmBp01UYIbn5BsJO9/Hd27OKebz2LDLOpM6kHcRcv/yeR2n9PGIR52QArvWnMc2PaCp+FIF+k14SgVXQED85/D0r0gOjl5S9TJ4KG9tnxNkfVeWSh3ewe4Jw= 37 | secret_access_key: 38 | secure: dbXIgLNNvOgEhR1Y9QGAH0fQb+QVbgBLzld0sPNtcVtflRp81tgUV6enIH7EYxS3jlbQtVnu6wsuvy9i58mea+LTJN8hpuP5XfFt8CEDs55lmsqX6WLfCi3zUhl+ykRD3zixMMqZkW2XiDUm5ZtLtvcltrnYbQlWARKPYChr+9z8wrcHAks21a1yr4A/BoDfNFNIFCcPbV4xWH+ejDs+EJfQ3Hf7+E8xkHGb7/43RkY3GrCm/vc2FfprQ4WNNVIfyPRvrgqn0kJR+um/QXLEXQzL0KcNA8UmRmCryUqwgymEpHQMv4WUC/cO0wElLJHrW10tfCy+F6HcSYiYO3748ZG9ouaReTixAikrekSAyLKFmWRVoLQeUx8ZyTqkxJFH5v9uJz4WZxY9vmNuK2L+jhX03LK9FpL+AIgWTVzQ/Jni/48FjZBS46pu/9Kh8EMjeA8Ali/qDzSmG78NQ5LQBGUK2rua/3fenqlG28OwSwOiCe6DnX7TA/YcQvOP15+Y3CQoDytaIVCv8HPQgFG0jPg7869FZeqQV8UPmYViIGGno0E1XQqKfE8tlhrKec8Pz+qEY5pbHzMs8BJ9iTddsgzxhPRfll3QKCq/uxCfyE7JVBEuc/eyBx9sPsQd2n2S1aiGOg6yBObBv89EDjLGQcLTOCS10E1LCfKlRTypzcQ= 39 | -------------------------------------------------------------------------------- /aws/ecs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Weaveworks ECS Image (2017-09-07) 2 | 3 | New features: 4 | - Update base AMIs to 2017.03.f, Weave Scope to 1.6.4 and Weave Net version to 2.0.4 5 | [#133](github.com/weaveworks/integrations/pull/133) 6 | 7 | ## Weaveworks ECS Image (2017-03-29) 8 | 9 | New features: 10 | - Update base AMIs to 2016.09.g, Weave Scope to 1.3.0 and Weave Net version to 1.9.4 11 | [#123](github.com/weaveworks/integrations/pull/123) 12 | 13 | ## Weaveworks ECS Image (2016-11-29) 14 | New features [#117](github.com/weaveworks/integrations/pull/117): 15 | - Update Weave Net to 1.8.1 16 | - Update Weave Scope to 1.1.0 17 | - Enable Scope ECS views 18 | - Add documentation for new actions required for Scope ECS views 19 | - Update base ECS images (including new Ohio region) 20 | 21 | ## Weaveworks ECS Image (2016-09-22) 22 | 23 | New features: 24 | - Update base AMIs to 2016.03.i and Weave Version to 1.6.2 [#108](github.com/weaveworks/integrations/pull/108) 25 | 26 | ## Weaveworks ECS Image (2016-08-22) 27 | 28 | New features: 29 | - Upgrade Weave Net to version 1.6.1, Weave Scope to version 0.17.1 and update base AMI to version `2016.03.g` [#105](github.com/weaveworks/integrations/pull/105) 30 | 31 | ## Weaveworks ECS Image (2016-06-21) 32 | 33 | New features: 34 | - Upgrade Weave Net to version 1.6.0 and Weave Scope to version 0.16.0 [#98](github.com/weaveworks/integrations/pull/98) 35 | 36 | ## Weaveworks ECS Image (2016-06-10) 37 | 38 | New features: 39 | - Upgrade base AMI to `2016.03.c`, upgrade Weave Net to version 1.5.2 and Weave Scope to version 0.15.0 [#94](github.com/weaveworks/integrations/pull/94) 40 | 41 | 42 | ## Weaveworks ECS Image (2016-04-25) 43 | 44 | New features: 45 | - Upgrade base AMI to `2016.03.a`, upgrade Weave Net to version 1.5.0 and Weave Scope to version 0.14.0 [#91](https://github.com/weaveworks/integrations/pull/91) 46 | - Use upstream packer [#90](https://github.com/weaveworks/integrations/pull/90) 47 | 48 | Bug fixes: 49 | - Launch Weave Scope correctly in Service mode [31e2c2640](https://github.com/weaveworks/integrations/commit/31e2c26405f52b3731684369185d9c868a08d281) 50 | 51 | ## Weaveworks ECS Image (2016-03-08) 52 | 53 | New features: 54 | - Use weave:peerGroupName tag to identify peers [#75](https://github.com/weaveworks/integrations/pull/75) 55 | - Discover Weave Apps using the Weave Network [#79](https://github.com/weaveworks/integrations/pull/79) 56 | - Upgrade base AMI to `2015.09.g` [#81](https://github.com/weaveworks/integrations/pull/82) 57 | - Upgrade Weave Net to version 1.4.5 [#80](https://github.com/weaveworks/integrations/pull/80) 58 | - Upgrade Weave Scope to version 0.13.1 [#78](https://github.com/weaveworks/integrations/pull/78) 59 | 60 | 61 | ## Weaveworks ECS Image (2016-01-15) 62 | 63 | New features: 64 | - Upgrade base AMI to `2015.09.d` 65 | - Upgrade Weave Net to version 1.4.2 [#57](https://github.com/weaveworks/integrations/pull/57) 66 | 67 | ## Weaveworks ECS Image (2015-12-17.b) 68 | 69 | Bug fixes: 70 | - Really make sure Weave Scope starts after Weave Net 71 | [#51](https://github.com/weaveworks/integrations/issues/51) 72 | 73 | 74 | ## Weaveworks ECS Image (2015-12-17) 75 | 76 | New features: 77 | - Upgrade base AMI to `2015.09.c` and include two new regions (eu-central-1 and ap-southeast-1) 78 | [#47](https://github.com/weaveworks/integrations/pull/47) 79 | - Upgrade Weave Net/Run to version 1.4.0 80 | [#46](https://github.com/weaveworks/integrations/pull/46) 81 | - Upgrade Weave Scope to version 0.11.1 82 | [#49](https://github.com/weaveworks/integrations/pull/49) 83 | 84 | 85 | ## Weaveworks ECS Image (2015-11-23) 86 | 87 | New features: 88 | - Upgrade base AMI to `2015.09.b` 89 | [#39](https://github.com/weaveworks/integrations/pull/39) 90 | - Upgrade Weave Net/Run version 1.3.1 and Weave Scope to version 0.10.0 91 | [#38](https://github.com/weaveworks/integrations/pull/38) 92 | 93 | Bug fixes: 94 | - Scope won't be able to inspect the Weave network if started after Weave 95 | [#35](https://github.com/weaveworks/integrations/issues/35) 96 | 97 | 98 | ## Weaveworks ECS Image (2015-10-26) 99 | 100 | Bug fixes: 101 | - Really bundle Weave 1.2 102 | [#33](https://github.com/weaveworks/integrations/issues/33) 103 | 104 | ## Weaveworks ECS Image (2015-10-22) 105 | 106 | New features: 107 | - Update base images to the latest version (2015.09.a) 108 | [#30](https://github.com/weaveworks/integrations/pull/10) 109 | - Use Weave 1.2 (**EDIT**: not really, the 2015-10-26 release fixes this) 110 | [#31](https://github.com/weaveworks/integrations/pull/31) 111 | 112 | Bug fixes: 113 | - Weave proxy unexpectedly closes the connection when spawning the ecs-agent. 114 | (implicitly fixed by upgrading to Weave 1.2, see 115 | [weave/#1514](https://github.com/weaveworks/weave/issues/1514)) 116 | 117 | 118 | ## Weaveworks ECS Image (2015-10-07) 119 | 120 | New features: 121 | - Update base images to the latest version (2015.03.g). 122 | [#10](https://github.com/weaveworks/integrations/pull/10) 123 | - Make Upstart jobs more robust 124 | [#2](https://github.com/weaveworks/integrations/issues/2) 125 | - Use Scope 0.8.0 126 | [#7](https://github.com/weaveworks/integrations/pull/7) 127 | - Use Weave 1.1.1 128 | [#18](https://github.com/weaveworks/integrations/pull/18) 129 | 130 | Bug fixes: 131 | - `/etc/init/ecs.conf` gets overwritten when upgrading the ecs-init package 132 | [#4](https://github.com/weaveworks/integrations/issues/4) 133 | - ECS doesn't stop correctly 134 | [#11](https://github.com/weaveworks/integrations/issues/11) 135 | - Upstart hangs on ECS' pre-start if Weave couldn't start 136 | [#16](https://github.com/weaveworks/integrations/issues/16) 137 | - Start ECS only after Weave proxy is ready to take requests 138 | [#13](https://github.com/weaveworks/integrations/issues/13) 139 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | Copyright 2014-2016 Weaveworks Ltd. 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | http://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. 192 | -------------------------------------------------------------------------------- /aws/ecs/cloudformation-no-app.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "Weave-enabled AWS CloudFormation template to create resources required to run tasks on an ECS cluster.", 4 | "Outputs": { 5 | "WeaveScope": { 6 | "Condition": "UseWeaveScopeStandalone", 7 | "Value": { 8 | "Fn::Join": [ 9 | "", 10 | [ 11 | "http://", 12 | { 13 | "Fn::GetAtt": [ 14 | "EcsFrontendElasticLoadBalancing", 15 | "DNSName" 16 | ] 17 | }, 18 | ":4040" 19 | ] 20 | ] 21 | }, 22 | "Description": "Weave Scope UI" 23 | } 24 | }, 25 | "Mappings": { 26 | "VpcCidrs": { 27 | "vpc": { 28 | "cidr": "172.31.0.0/16" 29 | }, 30 | "pubsubnet1": { 31 | "cidr": "172.31.0.0/24" 32 | }, 33 | "pubsubnet2": { 34 | "cidr": "172.31.1.0/24" 35 | } 36 | }, 37 | "WeaveworksEcsAmiIds": { 38 | "us-east-1": { 39 | "ImageId": "ami-9eb4b1e5" 40 | }, 41 | "us-east-2": { 42 | "ImageId": "ami-1c002379" 43 | }, 44 | "us-west-1": { 45 | "ImageId": "ami-4a2c192a" 46 | }, 47 | "us-west-2": { 48 | "ImageId": "ami-1d668865" 49 | }, 50 | "eu-west-1": { 51 | "ImageId": "ami-8fcc32f6" 52 | }, 53 | "eu-west-2": { 54 | "ImageId": "ami-cb1101af" 55 | }, 56 | "eu-central-1": { 57 | "ImageId": "ami-0460cb6b" 58 | }, 59 | "ap-northeast-1": { 60 | "ImageId": "ami-b743bed1" 61 | }, 62 | "ap-southeast-1": { 63 | "ImageId": "ami-9d1f7efe" 64 | }, 65 | "ap-southeast-2": { 66 | "ImageId": "ami-c1a6bda2" 67 | }, 68 | "ca-central-1": { 69 | "ImageId": "ami-b677c9d2" 70 | } 71 | } 72 | }, 73 | "Parameters": { 74 | "EcsInstanceType": { 75 | "Type": "String", 76 | "Description": "Type of the EC2 instance(s) to deploy", 77 | "Default": "t2.micro", 78 | "AllowedValues": [ 79 | "t2.micro", 80 | "t2.small", 81 | "t2.medium", 82 | "t2.large", 83 | "m3.medium", 84 | "m3.large", 85 | "m3.xlarge", 86 | "m3.2xlarge", 87 | "m4.large", 88 | "m4.xlarge", 89 | "m4.2xlarge", 90 | "m4.4xlarge", 91 | "m4.10xlarge", 92 | "c4.large", 93 | "c4.xlarge", 94 | "c4.2xlarge", 95 | "c4.4xlarge", 96 | "c4.8xlarge", 97 | "c3.large", 98 | "c3.xlarge", 99 | "c3.2xlarge", 100 | "c3.4xlarge", 101 | "c3.8xlarge", 102 | "r3.large", 103 | "r3.xlarge", 104 | "r3.2xlarge", 105 | "r3.4xlarge", 106 | "r3.8xlarge", 107 | "i2.xlarge", 108 | "i2.2xlarge", 109 | "i2.4xlarge", 110 | "i2.8xlarge" 111 | ], 112 | "ConstraintDescription": "must be a valid EC2 instance type." 113 | }, 114 | "Scale": { 115 | "Type": "Number", 116 | "Description": "Size of ECS cluster", 117 | "Default": "3" 118 | }, 119 | "KeyName": { 120 | "Type": "AWS::EC2::KeyPair::KeyName", 121 | "Description": "Name of an existing EC2 KeyPair to enable SSH access to the ECS instances (if none appear in drop-down menu, you need to create one)", 122 | "MinLength": "1", 123 | "ConstraintDescription": "must be the name of an existing EC2 KeyPair." 124 | }, 125 | "WeaveCloudServiceToken": { 126 | "Type": "String", 127 | "Description": "Optional - Authentication token for Weave Cloud [https://cloud.weave.works/]. Leave empty to run Scope in Standalone Mode.", 128 | "Default": "" 129 | } 130 | }, 131 | "Conditions": { 132 | "UseWeaveScopeStandalone": { 133 | "Fn::Equals": [ 134 | { 135 | "Ref": "WeaveCloudServiceToken" 136 | }, 137 | "" 138 | ] 139 | } 140 | }, 141 | "Resources": { 142 | "EcsCluster": { 143 | "Type": "AWS::ECS::Cluster" 144 | }, 145 | "Vpc": { 146 | "Type": "AWS::EC2::VPC", 147 | "Properties": { 148 | "CidrBlock": { 149 | "Fn::FindInMap": [ 150 | "VpcCidrs", 151 | "vpc", 152 | "cidr" 153 | ] 154 | } 155 | } 156 | }, 157 | "PubSubnetAz1": { 158 | "Type": "AWS::EC2::Subnet", 159 | "Properties": { 160 | "VpcId": { 161 | "Ref": "Vpc" 162 | }, 163 | "CidrBlock": { 164 | "Fn::FindInMap": [ 165 | "VpcCidrs", 166 | "pubsubnet1", 167 | "cidr" 168 | ] 169 | }, 170 | "AvailabilityZone": { 171 | "Fn::Select": [ 172 | "0", 173 | { 174 | "Fn::GetAZs": { 175 | "Ref": "AWS::Region" 176 | } 177 | } 178 | ] 179 | } 180 | } 181 | }, 182 | "PubSubnetAz2": { 183 | "Type": "AWS::EC2::Subnet", 184 | "Properties": { 185 | "VpcId": { 186 | "Ref": "Vpc" 187 | }, 188 | "CidrBlock": { 189 | "Fn::FindInMap": [ 190 | "VpcCidrs", 191 | "pubsubnet2", 192 | "cidr" 193 | ] 194 | }, 195 | "AvailabilityZone": { 196 | "Fn::Select": [ 197 | "1", 198 | { 199 | "Fn::GetAZs": { 200 | "Ref": "AWS::Region" 201 | } 202 | } 203 | ] 204 | } 205 | } 206 | }, 207 | "InternetGateway": { 208 | "Type": "AWS::EC2::InternetGateway" 209 | }, 210 | "AttachGateway": { 211 | "Type": "AWS::EC2::VPCGatewayAttachment", 212 | "Properties": { 213 | "VpcId": { 214 | "Ref": "Vpc" 215 | }, 216 | "InternetGatewayId": { 217 | "Ref": "InternetGateway" 218 | } 219 | } 220 | }, 221 | "RouteViaIgw": { 222 | "Type": "AWS::EC2::RouteTable", 223 | "Properties": { 224 | "VpcId": { 225 | "Ref": "Vpc" 226 | } 227 | } 228 | }, 229 | "PublicRouteViaIgw": { 230 | "DependsOn": "AttachGateway", 231 | "Type": "AWS::EC2::Route", 232 | "Properties": { 233 | "RouteTableId": { 234 | "Ref": "RouteViaIgw" 235 | }, 236 | "DestinationCidrBlock": "0.0.0.0/0", 237 | "GatewayId": { 238 | "Ref": "InternetGateway" 239 | } 240 | } 241 | }, 242 | "PubSubnet1RouteTableAssociation": { 243 | "Type": "AWS::EC2::SubnetRouteTableAssociation", 244 | "Properties": { 245 | "SubnetId": { 246 | "Ref": "PubSubnetAz1" 247 | }, 248 | "RouteTableId": { 249 | "Ref": "RouteViaIgw" 250 | } 251 | } 252 | }, 253 | "PubSubnet2RouteTableAssociation": { 254 | "Type": "AWS::EC2::SubnetRouteTableAssociation", 255 | "Properties": { 256 | "SubnetId": { 257 | "Ref": "PubSubnetAz2" 258 | }, 259 | "RouteTableId": { 260 | "Ref": "RouteViaIgw" 261 | } 262 | } 263 | }, 264 | "EcsSecurityGroup": { 265 | "Type": "AWS::EC2::SecurityGroup", 266 | "Properties": { 267 | "GroupDescription": "ECS Allowed Ports", 268 | "VpcId": { 269 | "Ref": "Vpc" 270 | } 271 | } 272 | }, 273 | "EcsSecurityGroupIngressAppPort": { 274 | "Type": "AWS::EC2::SecurityGroupIngress", 275 | "Properties": { 276 | "GroupId": { 277 | "Ref": "EcsSecurityGroup" 278 | }, 279 | "IpProtocol": "tcp", 280 | "FromPort": "80", 281 | "ToPort": "80", 282 | "CidrIp": "0.0.0.0/0" 283 | } 284 | }, 285 | "EcsSecurityGroupIngressSshPort": { 286 | "Type": "AWS::EC2::SecurityGroupIngress", 287 | "Properties": { 288 | "GroupId": { 289 | "Ref": "EcsSecurityGroup" 290 | }, 291 | "IpProtocol": "tcp", 292 | "FromPort": "22", 293 | "ToPort": "22", 294 | "CidrIp": "0.0.0.0/0" 295 | } 296 | }, 297 | "EcsSecurityGroupIngressWeaveScopeExtPort": { 298 | "Type": "AWS::EC2::SecurityGroupIngress", 299 | "Properties": { 300 | "GroupId": { 301 | "Ref": "EcsSecurityGroup" 302 | }, 303 | "IpProtocol": "tcp", 304 | "FromPort": "4040", 305 | "ToPort": "4040", 306 | "CidrIp": "0.0.0.0/0" 307 | } 308 | }, 309 | "EcsSecurityGroupIngressWeaveScopeIntPort": { 310 | "Type": "AWS::EC2::SecurityGroupIngress", 311 | "Properties": { 312 | "GroupId": { 313 | "Ref": "EcsSecurityGroup" 314 | }, 315 | "IpProtocol": "tcp", 316 | "FromPort": "4040", 317 | "ToPort": "4040", 318 | "SourceSecurityGroupId": { 319 | "Ref": "EcsSecurityGroup" 320 | } 321 | } 322 | }, 323 | "EcsSecurityGroupIngressWeaveNetIntTcpPort": { 324 | "Type": "AWS::EC2::SecurityGroupIngress", 325 | "Properties": { 326 | "GroupId": { 327 | "Ref": "EcsSecurityGroup" 328 | }, 329 | "IpProtocol": "tcp", 330 | "FromPort": "6783", 331 | "ToPort": "6783", 332 | "SourceSecurityGroupId": { 333 | "Ref": "EcsSecurityGroup" 334 | } 335 | } 336 | }, 337 | "EcsSecurityGroupIngressWeaveNetIntUdpPorts": { 338 | "Type": "AWS::EC2::SecurityGroupIngress", 339 | "Properties": { 340 | "GroupId": { 341 | "Ref": "EcsSecurityGroup" 342 | }, 343 | "IpProtocol": "udp", 344 | "FromPort": "6783", 345 | "ToPort": "6784", 346 | "SourceSecurityGroupId": { 347 | "Ref": "EcsSecurityGroup" 348 | } 349 | } 350 | }, 351 | "EcsInstancePolicy": { 352 | "Type": "AWS::IAM::Role", 353 | "Properties": { 354 | "AssumeRolePolicyDocument": { 355 | "Version": "2012-10-17", 356 | "Statement": [ 357 | { 358 | "Effect": "Allow", 359 | "Principal": { 360 | "Service": [ 361 | "ec2.amazonaws.com" 362 | ] 363 | }, 364 | "Action": [ 365 | "sts:AssumeRole" 366 | ] 367 | } 368 | ] 369 | }, 370 | "Path": "/", 371 | "ManagedPolicyArns": [ 372 | "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" 373 | ], 374 | "Policies": [ 375 | { 376 | "PolicyName": "ClusterInstanceRole", 377 | "PolicyDocument": { 378 | "Version": "2012-10-17", 379 | "Statement": [ 380 | { 381 | "Effect": "Allow", 382 | "Action": [ 383 | "ecs:CreateCluster", 384 | "ecs:DeregisterContainerInstance", 385 | "ecs:DiscoverPollEndpoint", 386 | "ecs:Poll", 387 | "ecs:RegisterContainerInstance", 388 | "ecs:Submit*", 389 | "ecs:ListClusters", 390 | "ecs:ListContainerInstances", 391 | "ecs:DescribeContainerInstances", 392 | "ecs:ListServices", 393 | "ecs:DescribeTasks", 394 | "ecs:DescribeServices", 395 | "ec2:DescribeInstances", 396 | "ec2:DescribeTags", 397 | "autoscaling:DescribeAutoScalingInstances" 398 | ], 399 | "Resource": [ 400 | "*" 401 | ] 402 | } 403 | ] 404 | } 405 | } 406 | ] 407 | } 408 | }, 409 | "EcsInstanceProfile": { 410 | "Type": "AWS::IAM::InstanceProfile", 411 | "Properties": { 412 | "Path": "/", 413 | "Roles": [ 414 | { 415 | "Ref": "EcsInstancePolicy" 416 | } 417 | ] 418 | } 419 | }, 420 | "EcsInstanceLc": { 421 | "Type": "AWS::AutoScaling::LaunchConfiguration", 422 | "Properties": { 423 | "ImageId": { 424 | "Fn::FindInMap": [ 425 | "WeaveworksEcsAmiIds", 426 | { 427 | "Ref": "AWS::Region" 428 | }, 429 | "ImageId" 430 | ] 431 | }, 432 | "InstanceType": { 433 | "Ref": "EcsInstanceType" 434 | }, 435 | "AssociatePublicIpAddress": true, 436 | "IamInstanceProfile": { 437 | "Ref": "EcsInstanceProfile" 438 | }, 439 | "KeyName": { 440 | "Ref": "KeyName" 441 | }, 442 | "SecurityGroups": [ 443 | { 444 | "Ref": "EcsSecurityGroup" 445 | } 446 | ], 447 | "UserData": { 448 | "Fn::Base64": { 449 | "Fn::Join": [ 450 | "\n", 451 | [ 452 | "#!/bin/bash -ex", 453 | "yum install -y aws-cfn-bootstrap", 454 | { 455 | "Fn::Join": [ 456 | " ", 457 | [ 458 | "/opt/aws/bin/cfn-init", 459 | "--verbose", 460 | "--stack", 461 | { 462 | "Ref": "AWS::StackName" 463 | }, 464 | "--region", 465 | { 466 | "Ref": "AWS::Region" 467 | }, 468 | "--resource", 469 | "EcsInstanceLc" 470 | ] 471 | ] 472 | } 473 | ] 474 | ] 475 | } 476 | } 477 | }, 478 | "Metadata": { 479 | "AWS::CloudFormation::Init": { 480 | "config": { 481 | "packages": { 482 | "yum": { 483 | "jq": [] 484 | }, 485 | "python": { 486 | "awscli": [] 487 | } 488 | }, 489 | "files": { 490 | "/etc/ecs/ecs.config": { 491 | "content": { 492 | "Fn::Join": [ 493 | "", 494 | [ 495 | "ECS_CLUSTER=", 496 | { 497 | "Ref": "EcsCluster" 498 | } 499 | ] 500 | ] 501 | } 502 | }, 503 | "/etc/weave/scope.config": { 504 | "content": { 505 | "Fn::Join": [ 506 | "", 507 | [ 508 | { 509 | "Fn::If": [ 510 | "UseWeaveScopeStandalone", 511 | "## SERVICE_TOKEN=", 512 | "SERVICE_TOKEN=" 513 | ] 514 | }, 515 | { 516 | "Fn::If": [ 517 | "UseWeaveScopeStandalone", 518 | "", 519 | { 520 | "Ref": "WeaveCloudServiceToken" 521 | } 522 | ] 523 | } 524 | ] 525 | ] 526 | } 527 | }, 528 | "/etc/init/ecs.override": { 529 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/ecs.override" 530 | }, 531 | "/etc/init/weave.conf": { 532 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/weave.conf" 533 | }, 534 | "/etc/init/scope.conf": { 535 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/scope.conf" 536 | }, 537 | "/etc/weave/run.sh": { 538 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/run.sh", 539 | "mode": "000755" 540 | }, 541 | "/etc/weave/peers.sh": { 542 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/peers.sh", 543 | "mode": "000755" 544 | }, 545 | "/usr/local/bin/weave": { 546 | "source": { 547 | "Fn::Join": [ 548 | "/", 549 | [ 550 | "https://github.com/weaveworks/weave/releases/download", 551 | "v2.0.4", 552 | "weave" 553 | ] 554 | ] 555 | }, 556 | "mode": "000755" 557 | }, 558 | "/usr/local/bin/scope": { 559 | "source": { 560 | "Fn::Join": [ 561 | "/", 562 | [ 563 | "https://github.com/weaveworks/scope/releases/download", 564 | "v1.6.4", 565 | "scope" 566 | ] 567 | ] 568 | }, 569 | "mode": "000755" 570 | } 571 | } 572 | } 573 | } 574 | } 575 | }, 576 | "EcsInstanceAsg": { 577 | "Type": "AWS::AutoScaling::AutoScalingGroup", 578 | "Properties": { 579 | "VPCZoneIdentifier": [ 580 | { 581 | "Fn::Join": [ 582 | ",", 583 | [ 584 | { 585 | "Ref": "PubSubnetAz1" 586 | }, 587 | { 588 | "Ref": "PubSubnetAz2" 589 | } 590 | ] 591 | ] 592 | } 593 | ], 594 | "LaunchConfigurationName": { 595 | "Ref": "EcsInstanceLc" 596 | }, 597 | "MinSize": "1", 598 | "MaxSize": { 599 | "Ref": "Scale" 600 | }, 601 | "DesiredCapacity": { 602 | "Ref": "Scale" 603 | }, 604 | "LoadBalancerNames": [ 605 | { 606 | "Ref": "EcsFrontendElasticLoadBalancing" 607 | } 608 | ], 609 | "Tags": [ 610 | { 611 | "Key": "Name", 612 | "Value": { 613 | "Fn::Join": [ 614 | "", 615 | [ 616 | "ECS Instance - ", 617 | { 618 | "Ref": "AWS::StackName" 619 | } 620 | ] 621 | ] 622 | }, 623 | "PropagateAtLaunch": "true" 624 | } 625 | ] 626 | } 627 | }, 628 | "EcsFrontendElasticLoadBalancing": { 629 | "Type": "AWS::ElasticLoadBalancing::LoadBalancer", 630 | "DependsOn": "InternetGateway", 631 | "Properties": { 632 | "Listeners": [ 633 | { 634 | "Fn::If": [ 635 | "UseWeaveScopeStandalone", 636 | { 637 | "InstancePort": "4040", 638 | "LoadBalancerPort": "4040", 639 | "InstanceProtocol": "TCP", 640 | "Protocol": "TCP" 641 | }, 642 | { 643 | "Ref": "AWS::NoValue" 644 | } 645 | ] 646 | } 647 | ], 648 | "SecurityGroups": [ 649 | { 650 | "Ref": "EcsSecurityGroup" 651 | } 652 | ], 653 | "Subnets": [ 654 | { 655 | "Ref": "PubSubnetAz1" 656 | }, 657 | { 658 | "Ref": "PubSubnetAz2" 659 | } 660 | ] 661 | } 662 | } 663 | } 664 | } 665 | -------------------------------------------------------------------------------- /aws/ecs/cloudformation.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "Weave-enabled AWS CloudFormation template to create resources required to run tasks on an ECS cluster. This template is simplified version of baseline template and provides less parameters.", 4 | "Mappings": { 5 | "VpcCidrs": { 6 | "vpc": { 7 | "cidr": "172.31.0.0/16" 8 | }, 9 | "pubsubnet1": { 10 | "cidr": "172.31.0.0/24" 11 | }, 12 | "pubsubnet2": { 13 | "cidr": "172.31.1.0/24" 14 | } 15 | }, 16 | "WeaveworksEcsAmiIds": { 17 | "us-east-1": { 18 | "ImageId": "ami-9eb4b1e5" 19 | }, 20 | "us-east-2": { 21 | "ImageId": "ami-1c002379" 22 | }, 23 | "us-west-1": { 24 | "ImageId": "ami-4a2c192a" 25 | }, 26 | "us-west-2": { 27 | "ImageId": "ami-1d668865" 28 | }, 29 | "eu-west-1": { 30 | "ImageId": "ami-8fcc32f6" 31 | }, 32 | "eu-west-2": { 33 | "ImageId": "ami-cb1101af" 34 | }, 35 | "eu-central-1": { 36 | "ImageId": "ami-0460cb6b" 37 | }, 38 | "ap-northeast-1": { 39 | "ImageId": "ami-b743bed1" 40 | }, 41 | "ap-southeast-1": { 42 | "ImageId": "ami-9d1f7efe" 43 | }, 44 | "ap-southeast-2": { 45 | "ImageId": "ami-c1a6bda2" 46 | }, 47 | "ca-central-1": { 48 | "ImageId": "ami-b677c9d2" 49 | } 50 | } 51 | }, 52 | "Parameters": { 53 | "EcsInstanceType": { 54 | "Type": "String", 55 | "Description": "ECS EC2 instance type", 56 | "Default": "t2.micro", 57 | "AllowedValues": [ 58 | "t2.micro", 59 | "t2.small", 60 | "t2.medium", 61 | "t2.large", 62 | "m3.medium", 63 | "m3.large", 64 | "m3.xlarge", 65 | "m3.2xlarge", 66 | "m4.large", 67 | "m4.xlarge", 68 | "m4.2xlarge", 69 | "m4.4xlarge", 70 | "m4.10xlarge", 71 | "c4.large", 72 | "c4.xlarge", 73 | "c4.2xlarge", 74 | "c4.4xlarge", 75 | "c4.8xlarge", 76 | "c3.large", 77 | "c3.xlarge", 78 | "c3.2xlarge", 79 | "c3.4xlarge", 80 | "c3.8xlarge", 81 | "r3.large", 82 | "r3.xlarge", 83 | "r3.2xlarge", 84 | "r3.4xlarge", 85 | "r3.8xlarge", 86 | "i2.xlarge", 87 | "i2.2xlarge", 88 | "i2.4xlarge", 89 | "i2.8xlarge" 90 | ], 91 | "ConstraintDescription": "must be a valid EC2 instance type." 92 | }, 93 | "Scale": { 94 | "Type": "Number", 95 | "Description": "Size of ECS cluster", 96 | "Default": "3" 97 | }, 98 | "KeyName": { 99 | "Type": "AWS::EC2::KeyPair::KeyName", 100 | "Description": "Name of an existing EC2 KeyPair to enable SSH access to the ECS instances (if none appear in drop-down menu, you need to create one)", 101 | "MinLength": "1", 102 | "ConstraintDescription": "must be the name of an existing EC2 KeyPair." 103 | }, 104 | "DeployExampleApp": { 105 | "Type": "String", 106 | "Description": "Deploy example app", 107 | "Default": "Yes", 108 | "AllowedValues": [ 109 | "Yes", 110 | "No" 111 | ], 112 | "ConstraintDescription": "must be Yes or No" 113 | }, 114 | "WeaveCloudServiceToken": { 115 | "Type": "String", 116 | "Description": "Optional - Authentication token for Weave Cloud [https://cloud.weave.works/]. Leave empty to run Scope in Standalone Mode.", 117 | "Default": "" 118 | }, 119 | "WeaveNetVersion": { 120 | "Type": "String", 121 | "Description": "Version of Weave Net to install", 122 | "Default": "v2.0.4" 123 | }, 124 | "WeaveScopeVersion": { 125 | "Type": "String", 126 | "Description": "Version of Weave Scope to install", 127 | "Default": "v1.6.4" 128 | } 129 | }, 130 | "Conditions": { 131 | "DoDeployExampleApp": { 132 | "Fn::Equals": [ 133 | { 134 | "Ref": "DeployExampleApp" 135 | }, 136 | "Yes" 137 | ] 138 | }, 139 | "UseScopeStandalone": { 140 | "Fn::Equals": [ 141 | { 142 | "Ref": "WeaveCloudServiceToken" 143 | }, 144 | "" 145 | ] 146 | } 147 | }, 148 | "Resources": { 149 | "EcsCluster": { 150 | "Type": "AWS::ECS::Cluster" 151 | }, 152 | "EcsBackendDataTask": { 153 | "Condition": "DoDeployExampleApp", 154 | "Type": "AWS::ECS::TaskDefinition", 155 | "Properties": { 156 | "ContainerDefinitions": [ 157 | { 158 | "Essential": true, 159 | "Name": "redis", 160 | "Image": "redis", 161 | "Cpu": 10, 162 | "Memory": 300 163 | } 164 | ], 165 | "Volumes": [] 166 | } 167 | }, 168 | "EcsBackendDataService": { 169 | "Condition": "DoDeployExampleApp", 170 | "Type": "AWS::ECS::Service", 171 | "Properties": { 172 | "Cluster": { 173 | "Ref": "EcsCluster" 174 | }, 175 | "DesiredCount": 1, 176 | "TaskDefinition": { 177 | "Ref": "EcsBackendDataTask" 178 | } 179 | } 180 | }, 181 | "EcsFrontendAppTask": { 182 | "Condition": "DoDeployExampleApp", 183 | "Type": "AWS::ECS::TaskDefinition", 184 | "Properties": { 185 | "ContainerDefinitions": [ 186 | { 187 | "PortMappings": [ 188 | { 189 | "HostPort": 80, 190 | "ContainerPort": 5000 191 | } 192 | ], 193 | "Essential": true, 194 | "Name": "hit-counter", 195 | "Image": "errordeveloper/hit-counter", 196 | "Command": [ 197 | "python", 198 | "app.py" 199 | ], 200 | "Cpu": 10, 201 | "Memory": 300 202 | } 203 | ], 204 | "Volumes": [] 205 | } 206 | }, 207 | "EcsFrontendAppService": { 208 | "Condition": "DoDeployExampleApp", 209 | "Type": "AWS::ECS::Service", 210 | "Properties": { 211 | "Cluster": { 212 | "Ref": "EcsCluster" 213 | }, 214 | "DesiredCount": { 215 | "Ref": "Scale" 216 | }, 217 | "TaskDefinition": { 218 | "Ref": "EcsFrontendAppTask" 219 | } 220 | } 221 | }, 222 | "Vpc": { 223 | "Type": "AWS::EC2::VPC", 224 | "Properties": { 225 | "CidrBlock": { 226 | "Fn::FindInMap": [ 227 | "VpcCidrs", 228 | "vpc", 229 | "cidr" 230 | ] 231 | } 232 | } 233 | }, 234 | "PubSubnetAz1": { 235 | "Type": "AWS::EC2::Subnet", 236 | "Properties": { 237 | "VpcId": { 238 | "Ref": "Vpc" 239 | }, 240 | "CidrBlock": { 241 | "Fn::FindInMap": [ 242 | "VpcCidrs", 243 | "pubsubnet1", 244 | "cidr" 245 | ] 246 | }, 247 | "AvailabilityZone": { 248 | "Fn::Select": [ 249 | "0", 250 | { 251 | "Fn::GetAZs": { 252 | "Ref": "AWS::Region" 253 | } 254 | } 255 | ] 256 | } 257 | } 258 | }, 259 | "PubSubnetAz2": { 260 | "Type": "AWS::EC2::Subnet", 261 | "Properties": { 262 | "VpcId": { 263 | "Ref": "Vpc" 264 | }, 265 | "CidrBlock": { 266 | "Fn::FindInMap": [ 267 | "VpcCidrs", 268 | "pubsubnet2", 269 | "cidr" 270 | ] 271 | }, 272 | "AvailabilityZone": { 273 | "Fn::Select": [ 274 | "1", 275 | { 276 | "Fn::GetAZs": { 277 | "Ref": "AWS::Region" 278 | } 279 | } 280 | ] 281 | } 282 | } 283 | }, 284 | "InternetGateway": { 285 | "Type": "AWS::EC2::InternetGateway" 286 | }, 287 | "AttachGateway": { 288 | "Type": "AWS::EC2::VPCGatewayAttachment", 289 | "Properties": { 290 | "VpcId": { 291 | "Ref": "Vpc" 292 | }, 293 | "InternetGatewayId": { 294 | "Ref": "InternetGateway" 295 | } 296 | } 297 | }, 298 | "RouteViaIgw": { 299 | "Type": "AWS::EC2::RouteTable", 300 | "Properties": { 301 | "VpcId": { 302 | "Ref": "Vpc" 303 | } 304 | } 305 | }, 306 | "PublicRouteViaIgw": { 307 | "DependsOn": "AttachGateway", 308 | "Type": "AWS::EC2::Route", 309 | "Properties": { 310 | "RouteTableId": { 311 | "Ref": "RouteViaIgw" 312 | }, 313 | "DestinationCidrBlock": "0.0.0.0/0", 314 | "GatewayId": { 315 | "Ref": "InternetGateway" 316 | } 317 | } 318 | }, 319 | "PubSubnet1RouteTableAssociation": { 320 | "Type": "AWS::EC2::SubnetRouteTableAssociation", 321 | "Properties": { 322 | "SubnetId": { 323 | "Ref": "PubSubnetAz1" 324 | }, 325 | "RouteTableId": { 326 | "Ref": "RouteViaIgw" 327 | } 328 | } 329 | }, 330 | "PubSubnet2RouteTableAssociation": { 331 | "Type": "AWS::EC2::SubnetRouteTableAssociation", 332 | "Properties": { 333 | "SubnetId": { 334 | "Ref": "PubSubnetAz2" 335 | }, 336 | "RouteTableId": { 337 | "Ref": "RouteViaIgw" 338 | } 339 | } 340 | }, 341 | "EcsSecurityGroup": { 342 | "Type": "AWS::EC2::SecurityGroup", 343 | "Properties": { 344 | "GroupDescription": "ECS Allowed Ports", 345 | "VpcId": { 346 | "Ref": "Vpc" 347 | } 348 | } 349 | }, 350 | "EcsSecurityGroupIngressAppPort": { 351 | "Type": "AWS::EC2::SecurityGroupIngress", 352 | "Properties": { 353 | "GroupId": { 354 | "Ref": "EcsSecurityGroup" 355 | }, 356 | "IpProtocol": "tcp", 357 | "FromPort": "80", 358 | "ToPort": "80", 359 | "CidrIp": "0.0.0.0/0" 360 | } 361 | }, 362 | "EcsSecurityGroupIngressSshPort": { 363 | "Type": "AWS::EC2::SecurityGroupIngress", 364 | "Properties": { 365 | "GroupId": { 366 | "Ref": "EcsSecurityGroup" 367 | }, 368 | "IpProtocol": "tcp", 369 | "FromPort": "22", 370 | "ToPort": "22", 371 | "CidrIp": "0.0.0.0/0" 372 | } 373 | }, 374 | "EcsSecurityGroupIngressWeaveScopeExtPort": { 375 | "Type": "AWS::EC2::SecurityGroupIngress", 376 | "Properties": { 377 | "GroupId": { 378 | "Ref": "EcsSecurityGroup" 379 | }, 380 | "IpProtocol": "tcp", 381 | "FromPort": "4040", 382 | "ToPort": "4040", 383 | "CidrIp": "0.0.0.0/0" 384 | } 385 | }, 386 | "EcsSecurityGroupIngressWeaveScopeIntPort": { 387 | "Type": "AWS::EC2::SecurityGroupIngress", 388 | "Properties": { 389 | "GroupId": { 390 | "Ref": "EcsSecurityGroup" 391 | }, 392 | "IpProtocol": "tcp", 393 | "FromPort": "4040", 394 | "ToPort": "4040", 395 | "SourceSecurityGroupId": { 396 | "Ref": "EcsSecurityGroup" 397 | } 398 | } 399 | }, 400 | "EcsSecurityGroupIngressWeaveNetIntTcpPort": { 401 | "Type": "AWS::EC2::SecurityGroupIngress", 402 | "Properties": { 403 | "GroupId": { 404 | "Ref": "EcsSecurityGroup" 405 | }, 406 | "IpProtocol": "tcp", 407 | "FromPort": "6783", 408 | "ToPort": "6783", 409 | "SourceSecurityGroupId": { 410 | "Ref": "EcsSecurityGroup" 411 | } 412 | } 413 | }, 414 | "EcsSecurityGroupIngressWeaveNetIntUdpPorts": { 415 | "Type": "AWS::EC2::SecurityGroupIngress", 416 | "Properties": { 417 | "GroupId": { 418 | "Ref": "EcsSecurityGroup" 419 | }, 420 | "IpProtocol": "udp", 421 | "FromPort": "6783", 422 | "ToPort": "6784", 423 | "SourceSecurityGroupId": { 424 | "Ref": "EcsSecurityGroup" 425 | } 426 | } 427 | }, 428 | "EcsInstancePolicy": { 429 | "Type": "AWS::IAM::Role", 430 | "Properties": { 431 | "AssumeRolePolicyDocument": { 432 | "Version": "2012-10-17", 433 | "Statement": [ 434 | { 435 | "Effect": "Allow", 436 | "Principal": { 437 | "Service": [ 438 | "ec2.amazonaws.com" 439 | ] 440 | }, 441 | "Action": [ 442 | "sts:AssumeRole" 443 | ] 444 | } 445 | ] 446 | }, 447 | "Path": "/", 448 | "ManagedPolicyArns": [ 449 | "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" 450 | ], 451 | "Policies": [ 452 | { 453 | "PolicyName": "ClusterInstanceRole", 454 | "PolicyDocument": { 455 | "Version": "2012-10-17", 456 | "Statement": [ 457 | { 458 | "Effect": "Allow", 459 | "Action": [ 460 | "ecs:CreateCluster", 461 | "ecs:DeregisterContainerInstance", 462 | "ecs:DiscoverPollEndpoint", 463 | "ecs:Poll", 464 | "ecs:RegisterContainerInstance", 465 | "ecs:Submit*", 466 | "ecs:ListClusters", 467 | "ecs:ListContainerInstances", 468 | "ecs:DescribeContainerInstances", 469 | "ecs:ListServices", 470 | "ecs:DescribeTasks", 471 | "ecs:DescribeServices", 472 | "ec2:DescribeInstances", 473 | "ec2:DescribeTags", 474 | "autoscaling:DescribeAutoScalingInstances" 475 | ], 476 | "Resource": [ 477 | "*" 478 | ] 479 | } 480 | ] 481 | } 482 | } 483 | ] 484 | } 485 | }, 486 | "EcsInstanceProfile": { 487 | "Type": "AWS::IAM::InstanceProfile", 488 | "Properties": { 489 | "Path": "/", 490 | "Roles": [ 491 | { 492 | "Ref": "EcsInstancePolicy" 493 | } 494 | ] 495 | } 496 | }, 497 | "EcsInstanceLc": { 498 | "Type": "AWS::AutoScaling::LaunchConfiguration", 499 | "Properties": { 500 | "ImageId": { 501 | "Fn::FindInMap": [ 502 | "WeaveworksEcsAmiIds", 503 | { 504 | "Ref": "AWS::Region" 505 | }, 506 | "ImageId" 507 | ] 508 | }, 509 | "InstanceType": { 510 | "Ref": "EcsInstanceType" 511 | }, 512 | "AssociatePublicIpAddress": true, 513 | "IamInstanceProfile": { 514 | "Ref": "EcsInstanceProfile" 515 | }, 516 | "KeyName": { 517 | "Ref": "KeyName" 518 | }, 519 | "SecurityGroups": [ 520 | { 521 | "Ref": "EcsSecurityGroup" 522 | } 523 | ], 524 | "UserData": { 525 | "Fn::Base64": { 526 | "Fn::Join": [ 527 | "\n", 528 | [ 529 | "#!/bin/bash -ex", 530 | "yum install -y aws-cfn-bootstrap", 531 | { 532 | "Fn::Join": [ 533 | " ", 534 | [ 535 | "/opt/aws/bin/cfn-init", 536 | "--verbose", 537 | "--stack", 538 | { 539 | "Ref": "AWS::StackName" 540 | }, 541 | "--region", 542 | { 543 | "Ref": "AWS::Region" 544 | }, 545 | "--resource", 546 | "EcsInstanceLc" 547 | ] 548 | ] 549 | } 550 | ] 551 | ] 552 | } 553 | } 554 | }, 555 | "Metadata": { 556 | "AWS::CloudFormation::Init": { 557 | "config": { 558 | "packages": { 559 | "yum": { 560 | "jq": [] 561 | }, 562 | "python": { 563 | "awscli": [] 564 | } 565 | }, 566 | "files": { 567 | "/etc/ecs/ecs.config": { 568 | "content": { 569 | "Fn::Join": [ 570 | "", 571 | [ 572 | "ECS_CLUSTER=", 573 | { 574 | "Ref": "EcsCluster" 575 | } 576 | ] 577 | ] 578 | } 579 | }, 580 | "/etc/weave/scope.config": { 581 | "content": { 582 | "Fn::Join": [ 583 | "", 584 | [ 585 | { 586 | "Fn::If": [ 587 | "UseScopeStandalone", 588 | "## SERVICE_TOKEN=", 589 | "SERVICE_TOKEN=" 590 | ] 591 | }, 592 | { 593 | "Fn::If": [ 594 | "UseScopeStandalone", 595 | "", 596 | { 597 | "Ref": "WeaveCloudServiceToken" 598 | } 599 | ] 600 | } 601 | ] 602 | ] 603 | } 604 | }, 605 | "/etc/init/ecs.override": { 606 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/ecs.override" 607 | }, 608 | "/etc/init/weave.conf": { 609 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/weave.conf" 610 | }, 611 | "/etc/init/scope.conf": { 612 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/scope.conf" 613 | }, 614 | "/etc/weave/run.sh": { 615 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/run.sh", 616 | "mode": "000755" 617 | }, 618 | "/etc/weave/peers.sh": { 619 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/peers.sh", 620 | "mode": "000755" 621 | }, 622 | "/usr/local/bin/weave": { 623 | "source": { 624 | "Fn::Join": [ 625 | "/", 626 | [ 627 | "https://github.com/weaveworks/weave/releases/download", 628 | { 629 | "Ref": "WeaveNetVersion" 630 | }, 631 | "weave" 632 | ] 633 | ] 634 | }, 635 | "mode": "000755" 636 | }, 637 | "/usr/local/bin/scope": { 638 | "source": { 639 | "Fn::Join": [ 640 | "/", 641 | [ 642 | "https://github.com/weaveworks/scope/releases/download", 643 | { 644 | "Ref": "WeaveScopeVersion" 645 | }, 646 | "scope" 647 | ] 648 | ] 649 | }, 650 | "mode": "000755" 651 | } 652 | } 653 | } 654 | } 655 | } 656 | }, 657 | "EcsInstanceAsg": { 658 | "Type": "AWS::AutoScaling::AutoScalingGroup", 659 | "Properties": { 660 | "VPCZoneIdentifier": [ 661 | { 662 | "Fn::Join": [ 663 | ",", 664 | [ 665 | { 666 | "Ref": "PubSubnetAz1" 667 | }, 668 | { 669 | "Ref": "PubSubnetAz2" 670 | } 671 | ] 672 | ] 673 | } 674 | ], 675 | "LaunchConfigurationName": { 676 | "Ref": "EcsInstanceLc" 677 | }, 678 | "MinSize": "1", 679 | "MaxSize": { 680 | "Ref": "Scale" 681 | }, 682 | "DesiredCapacity": { 683 | "Ref": "Scale" 684 | }, 685 | "Tags": [ 686 | { 687 | "Key": "Name", 688 | "Value": { 689 | "Fn::Join": [ 690 | "", 691 | [ 692 | "ECS Instance - ", 693 | { 694 | "Ref": "AWS::StackName" 695 | } 696 | ] 697 | ] 698 | }, 699 | "PropagateAtLaunch": "true" 700 | } 701 | ] 702 | } 703 | } 704 | } 705 | } 706 | -------------------------------------------------------------------------------- /aws/ecs/cloudformation-larger-app.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "Weave-enabled AWS CloudFormation template to create resources required to run tasks on an ECS cluster. This is the baseline template.", 4 | "Mappings": { 5 | "VpcCidrs": { 6 | "vpc": { 7 | "cidr": "172.31.0.0/16" 8 | }, 9 | "pubsubnet1": { 10 | "cidr": "172.31.0.0/24" 11 | }, 12 | "pubsubnet2": { 13 | "cidr": "172.31.1.0/24" 14 | } 15 | }, 16 | "WeaveworksEcsAmiIds": { 17 | "us-east-1": { 18 | "ImageId": "ami-9eb4b1e5" 19 | }, 20 | "us-east-2": { 21 | "ImageId": "ami-1c002379" 22 | }, 23 | "us-west-1": { 24 | "ImageId": "ami-4a2c192a" 25 | }, 26 | "us-west-2": { 27 | "ImageId": "ami-1d668865" 28 | }, 29 | "eu-west-1": { 30 | "ImageId": "ami-8fcc32f6" 31 | }, 32 | "eu-west-2": { 33 | "ImageId": "ami-cb1101af" 34 | }, 35 | "eu-central-1": { 36 | "ImageId": "ami-0460cb6b" 37 | }, 38 | "ap-northeast-1": { 39 | "ImageId": "ami-b743bed1" 40 | }, 41 | "ap-southeast-1": { 42 | "ImageId": "ami-9d1f7efe" 43 | }, 44 | "ap-southeast-2": { 45 | "ImageId": "ami-c1a6bda2" 46 | }, 47 | "ca-central-1": { 48 | "ImageId": "ami-b677c9d2" 49 | } 50 | } 51 | }, 52 | "Parameters": { 53 | "EcsInstanceType": { 54 | "Type": "String", 55 | "Description": "ECS EC2 instance type", 56 | "Default": "m3.xlarge", 57 | "AllowedValues": [ 58 | "t2.micro", 59 | "t2.small", 60 | "t2.medium", 61 | "t2.large", 62 | "m3.medium", 63 | "m3.large", 64 | "m3.xlarge", 65 | "m3.2xlarge", 66 | "m4.large", 67 | "m4.xlarge", 68 | "m4.2xlarge", 69 | "m4.4xlarge", 70 | "m4.10xlarge", 71 | "c4.large", 72 | "c4.xlarge", 73 | "c4.2xlarge", 74 | "c4.4xlarge", 75 | "c4.8xlarge", 76 | "c3.large", 77 | "c3.xlarge", 78 | "c3.2xlarge", 79 | "c3.4xlarge", 80 | "c3.8xlarge", 81 | "r3.large", 82 | "r3.xlarge", 83 | "r3.2xlarge", 84 | "r3.4xlarge", 85 | "r3.8xlarge", 86 | "i2.xlarge", 87 | "i2.2xlarge", 88 | "i2.4xlarge", 89 | "i2.8xlarge" 90 | ], 91 | "ConstraintDescription": "must be a valid EC2 instance type." 92 | }, 93 | "Scale": { 94 | "Type": "Number", 95 | "Description": "Size of ECS cluster", 96 | "Default": "2" 97 | }, 98 | "KeyName": { 99 | "Type": "AWS::EC2::KeyPair::KeyName", 100 | "Description": "Name of an existing EC2 KeyPair to enable SSH access to the ECS instances (if none appear in drop-down menu, you need to create one)", 101 | "MinLength": "1", 102 | "ConstraintDescription": "must be the name of an existing EC2 KeyPair." 103 | }, 104 | "DeployExampleApp": { 105 | "Type": "String", 106 | "Description": "Deploy example app", 107 | "Default": "Yes", 108 | "AllowedValues": [ 109 | "Yes", 110 | "No" 111 | ], 112 | "ConstraintDescription": "must be Yes or No" 113 | }, 114 | "WeaveCloudServiceToken": { 115 | "Type": "String", 116 | "Description": "Optional - Authentication token for Weave Cloud [https://cloud.weave.works/]. Leave empty to run Scope in Standalone Mode.", 117 | "Default": "" 118 | }, 119 | "WeaveNetVersion": { 120 | "Type": "String", 121 | "Description": "Version of Weave Net to install", 122 | "Default": "v2.0.4" 123 | }, 124 | "WeaveScopeVersion": { 125 | "Type": "String", 126 | "Description": "Version of Weave Scope to install", 127 | "Default": "v1.6.4" 128 | } 129 | }, 130 | "Conditions": { 131 | "DoDeployExampleApp": { 132 | "Fn::Equals": [ 133 | { 134 | "Ref": "DeployExampleApp" 135 | }, 136 | "Yes" 137 | ] 138 | }, 139 | "UseScopeStandalone": { 140 | "Fn::Equals": [ 141 | { 142 | "Ref": "WeaveCloudServiceToken" 143 | }, 144 | "" 145 | ] 146 | } 147 | }, 148 | "Resources": { 149 | "EcsCluster": { 150 | "Type": "AWS::ECS::Cluster" 151 | }, 152 | "EcsBackendDataTask": { 153 | "Condition": "DoDeployExampleApp", 154 | "Type": "AWS::ECS::TaskDefinition", 155 | "Properties": { 156 | "ContainerDefinitions": [ 157 | { 158 | "Essential": true, 159 | "Name": "redis", 160 | "Image": "redis", 161 | "Cpu": 10, 162 | "Memory": 300 163 | }, 164 | { 165 | "Essential": true, 166 | "Name": "elasticsearch", 167 | "Image": "elasticsearch", 168 | "Cpu": 10, 169 | "Memory": 300 170 | } 171 | ], 172 | "Volumes": [] 173 | } 174 | }, 175 | "EcsBackendDataService": { 176 | "Condition": "DoDeployExampleApp", 177 | "Type": "AWS::ECS::Service", 178 | "Properties": { 179 | "Cluster": { 180 | "Ref": "EcsCluster" 181 | }, 182 | "DesiredCount": 1, 183 | "TaskDefinition": { 184 | "Ref": "EcsBackendDataTask" 185 | } 186 | } 187 | }, 188 | "EcsAppTask": { 189 | "Condition": "DoDeployExampleApp", 190 | "Type": "AWS::ECS::TaskDefinition", 191 | "Properties": { 192 | "ContainerDefinitions": [ 193 | { 194 | "Essential": true, 195 | "Name": "searchapp", 196 | "Image": "tomwilkie/searchapp", 197 | "Cpu": 10, 198 | "Memory": 300 199 | }, 200 | { 201 | "Essential": true, 202 | "Name": "qotd", 203 | "Image": "tomwilkie/qotd", 204 | "Cpu": 10, 205 | "Memory": 300 206 | }, 207 | { 208 | "Essential": true, 209 | "Name": "echo", 210 | "Image": "tomwilkie/echo", 211 | "Cpu": 10, 212 | "Memory": 300 213 | }, 214 | { 215 | "Essential": true, 216 | "Name": "app", 217 | "Image": "tomwilkie/app", 218 | "Cpu": 10, 219 | "Memory": 300 220 | }, 221 | { 222 | "Essential": true, 223 | "Name": "frontend", 224 | "Command": [ 225 | "/bin/sh", 226 | "-c", 227 | "sed -n 's/nameserver \\([.0-9]*\\)/\\1 dns\\.weave\\.local/p' /etc/resolv.conf | head -1 >> /etc/hosts && nginx -g 'daemon off;'" 228 | ], 229 | "Image": "tomwilkie/frontend", 230 | "PortMappings": [ 231 | { 232 | "HostPort": 80, 233 | "ContainerPort": 80 234 | } 235 | ], 236 | "Cpu": 10, 237 | "Memory": 300 238 | }, 239 | { 240 | "Essential": true, 241 | "Name": "client", 242 | "Image": "tomwilkie/client", 243 | "Cpu": 10, 244 | "Memory": 300 245 | } 246 | ], 247 | "Volumes": [] 248 | } 249 | }, 250 | "EcsAppService": { 251 | "Condition": "DoDeployExampleApp", 252 | "Type": "AWS::ECS::Service", 253 | "Properties": { 254 | "Cluster": { 255 | "Ref": "EcsCluster" 256 | }, 257 | "DesiredCount": { 258 | "Ref": "Scale" 259 | }, 260 | "TaskDefinition": { 261 | "Ref": "EcsAppTask" 262 | } 263 | } 264 | }, 265 | "Vpc": { 266 | "Type": "AWS::EC2::VPC", 267 | "Properties": { 268 | "CidrBlock": { 269 | "Fn::FindInMap": [ 270 | "VpcCidrs", 271 | "vpc", 272 | "cidr" 273 | ] 274 | } 275 | } 276 | }, 277 | "PubSubnetAz1": { 278 | "Type": "AWS::EC2::Subnet", 279 | "Properties": { 280 | "VpcId": { 281 | "Ref": "Vpc" 282 | }, 283 | "CidrBlock": { 284 | "Fn::FindInMap": [ 285 | "VpcCidrs", 286 | "pubsubnet1", 287 | "cidr" 288 | ] 289 | }, 290 | "AvailabilityZone": { 291 | "Fn::Select": [ 292 | "0", 293 | { 294 | "Fn::GetAZs": { 295 | "Ref": "AWS::Region" 296 | } 297 | } 298 | ] 299 | } 300 | } 301 | }, 302 | "PubSubnetAz2": { 303 | "Type": "AWS::EC2::Subnet", 304 | "Properties": { 305 | "VpcId": { 306 | "Ref": "Vpc" 307 | }, 308 | "CidrBlock": { 309 | "Fn::FindInMap": [ 310 | "VpcCidrs", 311 | "pubsubnet2", 312 | "cidr" 313 | ] 314 | }, 315 | "AvailabilityZone": { 316 | "Fn::Select": [ 317 | "1", 318 | { 319 | "Fn::GetAZs": { 320 | "Ref": "AWS::Region" 321 | } 322 | } 323 | ] 324 | } 325 | } 326 | }, 327 | "InternetGateway": { 328 | "Type": "AWS::EC2::InternetGateway" 329 | }, 330 | "AttachGateway": { 331 | "Type": "AWS::EC2::VPCGatewayAttachment", 332 | "Properties": { 333 | "VpcId": { 334 | "Ref": "Vpc" 335 | }, 336 | "InternetGatewayId": { 337 | "Ref": "InternetGateway" 338 | } 339 | } 340 | }, 341 | "RouteViaIgw": { 342 | "Type": "AWS::EC2::RouteTable", 343 | "Properties": { 344 | "VpcId": { 345 | "Ref": "Vpc" 346 | } 347 | } 348 | }, 349 | "PublicRouteViaIgw": { 350 | "DependsOn": "AttachGateway", 351 | "Type": "AWS::EC2::Route", 352 | "Properties": { 353 | "RouteTableId": { 354 | "Ref": "RouteViaIgw" 355 | }, 356 | "DestinationCidrBlock": "0.0.0.0/0", 357 | "GatewayId": { 358 | "Ref": "InternetGateway" 359 | } 360 | } 361 | }, 362 | "PubSubnet1RouteTableAssociation": { 363 | "Type": "AWS::EC2::SubnetRouteTableAssociation", 364 | "Properties": { 365 | "SubnetId": { 366 | "Ref": "PubSubnetAz1" 367 | }, 368 | "RouteTableId": { 369 | "Ref": "RouteViaIgw" 370 | } 371 | } 372 | }, 373 | "PubSubnet2RouteTableAssociation": { 374 | "Type": "AWS::EC2::SubnetRouteTableAssociation", 375 | "Properties": { 376 | "SubnetId": { 377 | "Ref": "PubSubnetAz2" 378 | }, 379 | "RouteTableId": { 380 | "Ref": "RouteViaIgw" 381 | } 382 | } 383 | }, 384 | "EcsSecurityGroup": { 385 | "Type": "AWS::EC2::SecurityGroup", 386 | "Properties": { 387 | "GroupDescription": "ECS Allowed Ports", 388 | "VpcId": { 389 | "Ref": "Vpc" 390 | } 391 | } 392 | }, 393 | "EcsSecurityGroupIngressAppPort": { 394 | "Type": "AWS::EC2::SecurityGroupIngress", 395 | "Properties": { 396 | "GroupId": { 397 | "Ref": "EcsSecurityGroup" 398 | }, 399 | "IpProtocol": "tcp", 400 | "FromPort": "80", 401 | "ToPort": "80", 402 | "CidrIp": "0.0.0.0/0" 403 | } 404 | }, 405 | "EcsSecurityGroupIngressSshPort": { 406 | "Type": "AWS::EC2::SecurityGroupIngress", 407 | "Properties": { 408 | "GroupId": { 409 | "Ref": "EcsSecurityGroup" 410 | }, 411 | "IpProtocol": "tcp", 412 | "FromPort": "22", 413 | "ToPort": "22", 414 | "CidrIp": "0.0.0.0/0" 415 | } 416 | }, 417 | "EcsSecurityGroupIngressWeaveScopeExtPort": { 418 | "Type": "AWS::EC2::SecurityGroupIngress", 419 | "Properties": { 420 | "GroupId": { 421 | "Ref": "EcsSecurityGroup" 422 | }, 423 | "IpProtocol": "tcp", 424 | "FromPort": "4040", 425 | "ToPort": "4040", 426 | "CidrIp": "0.0.0.0/0" 427 | } 428 | }, 429 | "EcsSecurityGroupIngressWeaveScopeIntPort": { 430 | "Type": "AWS::EC2::SecurityGroupIngress", 431 | "Properties": { 432 | "GroupId": { 433 | "Ref": "EcsSecurityGroup" 434 | }, 435 | "IpProtocol": "tcp", 436 | "FromPort": "4040", 437 | "ToPort": "4040", 438 | "SourceSecurityGroupId": { 439 | "Ref": "EcsSecurityGroup" 440 | } 441 | } 442 | }, 443 | "EcsSecurityGroupIngressWeaveNetIntTcpPort": { 444 | "Type": "AWS::EC2::SecurityGroupIngress", 445 | "Properties": { 446 | "GroupId": { 447 | "Ref": "EcsSecurityGroup" 448 | }, 449 | "IpProtocol": "tcp", 450 | "FromPort": "6783", 451 | "ToPort": "6783", 452 | "SourceSecurityGroupId": { 453 | "Ref": "EcsSecurityGroup" 454 | } 455 | } 456 | }, 457 | "EcsSecurityGroupIngressWeaveNetIntUdpPorts": { 458 | "Type": "AWS::EC2::SecurityGroupIngress", 459 | "Properties": { 460 | "GroupId": { 461 | "Ref": "EcsSecurityGroup" 462 | }, 463 | "IpProtocol": "udp", 464 | "FromPort": "6783", 465 | "ToPort": "6784", 466 | "SourceSecurityGroupId": { 467 | "Ref": "EcsSecurityGroup" 468 | } 469 | } 470 | }, 471 | "EcsInstancePolicy": { 472 | "Type": "AWS::IAM::Role", 473 | "Properties": { 474 | "AssumeRolePolicyDocument": { 475 | "Version": "2012-10-17", 476 | "Statement": [ 477 | { 478 | "Effect": "Allow", 479 | "Principal": { 480 | "Service": [ 481 | "ec2.amazonaws.com" 482 | ] 483 | }, 484 | "Action": [ 485 | "sts:AssumeRole" 486 | ] 487 | } 488 | ] 489 | }, 490 | "Path": "/", 491 | "ManagedPolicyArns": [ 492 | "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" 493 | ], 494 | "Policies": [ 495 | { 496 | "PolicyName": "ClusterInstanceRole", 497 | "PolicyDocument": { 498 | "Version": "2012-10-17", 499 | "Statement": [ 500 | { 501 | "Effect": "Allow", 502 | "Action": [ 503 | "ecs:CreateCluster", 504 | "ecs:DeregisterContainerInstance", 505 | "ecs:DiscoverPollEndpoint", 506 | "ecs:Poll", 507 | "ecs:RegisterContainerInstance", 508 | "ecs:Submit*", 509 | "ecs:ListClusters", 510 | "ecs:ListContainerInstances", 511 | "ecs:DescribeContainerInstances", 512 | "ecs:ListServices", 513 | "ecs:DescribeTasks", 514 | "ecs:DescribeServices", 515 | "ec2:DescribeInstances", 516 | "ec2:DescribeTags", 517 | "autoscaling:DescribeAutoScalingInstances" 518 | ], 519 | "Resource": [ 520 | "*" 521 | ] 522 | } 523 | ] 524 | } 525 | } 526 | ] 527 | } 528 | }, 529 | "EcsInstanceProfile": { 530 | "Type": "AWS::IAM::InstanceProfile", 531 | "Properties": { 532 | "Path": "/", 533 | "Roles": [ 534 | { 535 | "Ref": "EcsInstancePolicy" 536 | } 537 | ] 538 | } 539 | }, 540 | "EcsInstanceLc": { 541 | "Type": "AWS::AutoScaling::LaunchConfiguration", 542 | "Properties": { 543 | "ImageId": { 544 | "Fn::FindInMap": [ 545 | "WeaveworksEcsAmiIds", 546 | { 547 | "Ref": "AWS::Region" 548 | }, 549 | "ImageId" 550 | ] 551 | }, 552 | "InstanceType": { 553 | "Ref": "EcsInstanceType" 554 | }, 555 | "AssociatePublicIpAddress": true, 556 | "IamInstanceProfile": { 557 | "Ref": "EcsInstanceProfile" 558 | }, 559 | "KeyName": { 560 | "Ref": "KeyName" 561 | }, 562 | "SecurityGroups": [ 563 | { 564 | "Ref": "EcsSecurityGroup" 565 | } 566 | ], 567 | "UserData": { 568 | "Fn::Base64": { 569 | "Fn::Join": [ 570 | "\n", 571 | [ 572 | "#!/bin/bash -ex", 573 | "yum install -y aws-cfn-bootstrap", 574 | { 575 | "Fn::Join": [ 576 | " ", 577 | [ 578 | "/opt/aws/bin/cfn-init", 579 | "--verbose", 580 | "--stack", 581 | { 582 | "Ref": "AWS::StackName" 583 | }, 584 | "--region", 585 | { 586 | "Ref": "AWS::Region" 587 | }, 588 | "--resource", 589 | "EcsInstanceLc" 590 | ] 591 | ] 592 | } 593 | ] 594 | ] 595 | } 596 | } 597 | }, 598 | "Metadata": { 599 | "AWS::CloudFormation::Init": { 600 | "config": { 601 | "packages": { 602 | "yum": { 603 | "jq": [] 604 | }, 605 | "python": { 606 | "awscli": [] 607 | } 608 | }, 609 | "files": { 610 | "/etc/ecs/ecs.config": { 611 | "content": { 612 | "Fn::Join": [ 613 | "", 614 | [ 615 | "ECS_CLUSTER=", 616 | { 617 | "Ref": "EcsCluster" 618 | } 619 | ] 620 | ] 621 | } 622 | }, 623 | "/etc/weave/scope.config": { 624 | "content": { 625 | "Fn::Join": [ 626 | "", 627 | [ 628 | { 629 | "Fn::If": [ 630 | "UseScopeStandalone", 631 | "## SERVICE_TOKEN=", 632 | "SERVICE_TOKEN=" 633 | ] 634 | }, 635 | { 636 | "Fn::If": [ 637 | "UseScopeStandalone", 638 | "", 639 | { 640 | "Ref": "WeaveCloudServiceToken" 641 | } 642 | ] 643 | } 644 | ] 645 | ] 646 | } 647 | }, 648 | "/etc/init/ecs.override": { 649 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/ecs.override" 650 | }, 651 | "/etc/init/weave.conf": { 652 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/weave.conf" 653 | }, 654 | "/etc/init/scope.conf": { 655 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/scope.conf" 656 | }, 657 | "/etc/weave/run.sh": { 658 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/run.sh", 659 | "mode": "000755" 660 | }, 661 | "/etc/weave/peers.sh": { 662 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/peers.sh", 663 | "mode": "000755" 664 | }, 665 | "/usr/local/bin/weave": { 666 | "source": { 667 | "Fn::Join": [ 668 | "/", 669 | [ 670 | "https://github.com/weaveworks/weave/releases/download", 671 | { 672 | "Ref": "WeaveNetVersion" 673 | }, 674 | "weave" 675 | ] 676 | ] 677 | }, 678 | "mode": "000755" 679 | }, 680 | "/usr/local/bin/scope": { 681 | "source": { 682 | "Fn::Join": [ 683 | "/", 684 | [ 685 | "https://github.com/weaveworks/scope/releases/download", 686 | { 687 | "Ref": "WeaveScopeVersion" 688 | }, 689 | "scope" 690 | ] 691 | ] 692 | }, 693 | "mode": "000755" 694 | } 695 | } 696 | } 697 | } 698 | } 699 | }, 700 | "EcsInstanceAsg": { 701 | "Type": "AWS::AutoScaling::AutoScalingGroup", 702 | "Properties": { 703 | "VPCZoneIdentifier": [ 704 | { 705 | "Fn::Join": [ 706 | ",", 707 | [ 708 | { 709 | "Ref": "PubSubnetAz1" 710 | }, 711 | { 712 | "Ref": "PubSubnetAz2" 713 | } 714 | ] 715 | ] 716 | } 717 | ], 718 | "LaunchConfigurationName": { 719 | "Ref": "EcsInstanceLc" 720 | }, 721 | "MinSize": "1", 722 | "MaxSize": { 723 | "Ref": "Scale" 724 | }, 725 | "DesiredCapacity": { 726 | "Ref": "Scale" 727 | }, 728 | "Tags": [ 729 | { 730 | "Key": "Name", 731 | "Value": { 732 | "Fn::Join": [ 733 | "", 734 | [ 735 | "ECS Instance - ", 736 | { 737 | "Ref": "AWS::StackName" 738 | } 739 | ] 740 | ] 741 | }, 742 | "PropagateAtLaunch": "true" 743 | } 744 | ] 745 | } 746 | } 747 | } 748 | } 749 | -------------------------------------------------------------------------------- /aws/ecs/cloudformation-identiorca.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "Weave-enabled AWS CloudFormation template to create resources required to run tasks on an ECS cluster. This template uses a larger example app.", 4 | "Outputs": { 5 | "AppFrontend": { 6 | "Condition": "DoDeployExampleApp", 7 | "Value": { 8 | "Fn::Join": [ 9 | "", 10 | [ 11 | "http://", 12 | { 13 | "Fn::GetAtt": [ 14 | "EcsFrontendElasticLoadBalancing", 15 | "DNSName" 16 | ] 17 | }, 18 | ":80" 19 | ] 20 | ] 21 | }, 22 | "Description": "Identiorca app frontend" 23 | }, 24 | "WeaveScope": { 25 | "Condition": "UseWeaveScopeStandalone", 26 | "Value": { 27 | "Fn::Join": [ 28 | "", 29 | [ 30 | "http://", 31 | { 32 | "Fn::GetAtt": [ 33 | "EcsFrontendElasticLoadBalancing", 34 | "DNSName" 35 | ] 36 | }, 37 | ":4040" 38 | ] 39 | ] 40 | }, 41 | "Description": "Weave Scope UI" 42 | } 43 | }, 44 | "Mappings": { 45 | "VpcCidrs": { 46 | "vpc": { 47 | "cidr": "172.31.0.0/16" 48 | }, 49 | "pubsubnet1": { 50 | "cidr": "172.31.0.0/24" 51 | }, 52 | "pubsubnet2": { 53 | "cidr": "172.31.1.0/24" 54 | } 55 | }, 56 | "WeaveworksEcsAmiIds": { 57 | "us-east-1": { 58 | "ImageId": "ami-9eb4b1e5" 59 | }, 60 | "us-east-2": { 61 | "ImageId": "ami-1c002379" 62 | }, 63 | "us-west-1": { 64 | "ImageId": "ami-4a2c192a" 65 | }, 66 | "us-west-2": { 67 | "ImageId": "ami-1d668865" 68 | }, 69 | "eu-west-1": { 70 | "ImageId": "ami-8fcc32f6" 71 | }, 72 | "eu-west-2": { 73 | "ImageId": "ami-cb1101af" 74 | }, 75 | "eu-central-1": { 76 | "ImageId": "ami-0460cb6b" 77 | }, 78 | "ap-northeast-1": { 79 | "ImageId": "ami-b743bed1" 80 | }, 81 | "ap-southeast-1": { 82 | "ImageId": "ami-9d1f7efe" 83 | }, 84 | "ap-southeast-2": { 85 | "ImageId": "ami-c1a6bda2" 86 | }, 87 | "ca-central-1": { 88 | "ImageId": "ami-b677c9d2" 89 | } 90 | } 91 | }, 92 | "Parameters": { 93 | "EcsInstanceType": { 94 | "Type": "String", 95 | "Description": "Type of the EC2 instance(s) to deploy", 96 | "Default": "t2.micro", 97 | "AllowedValues": [ 98 | "t2.micro", 99 | "t2.small", 100 | "t2.medium", 101 | "t2.large", 102 | "m3.medium", 103 | "m3.large", 104 | "m3.xlarge", 105 | "m3.2xlarge", 106 | "m4.large", 107 | "m4.xlarge", 108 | "m4.2xlarge", 109 | "m4.4xlarge", 110 | "m4.10xlarge", 111 | "c4.large", 112 | "c4.xlarge", 113 | "c4.2xlarge", 114 | "c4.4xlarge", 115 | "c4.8xlarge", 116 | "c3.large", 117 | "c3.xlarge", 118 | "c3.2xlarge", 119 | "c3.4xlarge", 120 | "c3.8xlarge", 121 | "r3.large", 122 | "r3.xlarge", 123 | "r3.2xlarge", 124 | "r3.4xlarge", 125 | "r3.8xlarge", 126 | "i2.xlarge", 127 | "i2.2xlarge", 128 | "i2.4xlarge", 129 | "i2.8xlarge" 130 | ], 131 | "ConstraintDescription": "must be a valid EC2 instance type." 132 | }, 133 | "Scale": { 134 | "Type": "Number", 135 | "Description": "Size of ECS cluster", 136 | "Default": "3" 137 | }, 138 | "KeyName": { 139 | "Type": "AWS::EC2::KeyPair::KeyName", 140 | "Description": "Name of an existing EC2 KeyPair to enable SSH access to the ECS instances (if none appear in drop-down menu, you need to create one)", 141 | "MinLength": "1", 142 | "ConstraintDescription": "must be the name of an existing EC2 KeyPair." 143 | }, 144 | "DeployExampleApp": { 145 | "Type": "String", 146 | "Description": "No: only Weave Net/Scope net will be deployed, Yes: also deploy identiorca example application", 147 | "Default": "Yes", 148 | "AllowedValues": [ 149 | "Yes", 150 | "No" 151 | ], 152 | "ConstraintDescription": "must be Yes or No" 153 | }, 154 | "WeaveCloudServiceToken": { 155 | "Type": "String", 156 | "Description": "Optional - Authentication token for Weave Cloud [https://cloud.weave.works/]. Leave empty to run Scope in Standalone Mode.", 157 | "Default": "" 158 | } 159 | }, 160 | "Conditions": { 161 | "DoDeployExampleApp": { 162 | "Fn::Equals": [ 163 | { 164 | "Ref": "DeployExampleApp" 165 | }, 166 | "Yes" 167 | ] 168 | }, 169 | "UseWeaveScopeStandalone": { 170 | "Fn::Equals": [ 171 | { 172 | "Ref": "WeaveCloudServiceToken" 173 | }, 174 | "" 175 | ] 176 | } 177 | }, 178 | "Resources": { 179 | "EcsCluster": { 180 | "Type": "AWS::ECS::Cluster" 181 | }, 182 | "EcsBackendDataTask": { 183 | "Condition": "DoDeployExampleApp", 184 | "Type": "AWS::ECS::TaskDefinition", 185 | "Properties": { 186 | "ContainerDefinitions": [ 187 | { 188 | "Essential": true, 189 | "Name": "redis", 190 | "Image": "redis:3", 191 | "Cpu": 10, 192 | "Memory": 300 193 | } 194 | ], 195 | "Volumes": [] 196 | } 197 | }, 198 | "EcsBackendDataService": { 199 | "Condition": "DoDeployExampleApp", 200 | "Type": "AWS::ECS::Service", 201 | "Properties": { 202 | "Cluster": { 203 | "Ref": "EcsCluster" 204 | }, 205 | "DesiredCount": 1, 206 | "TaskDefinition": { 207 | "Ref": "EcsBackendDataTask" 208 | } 209 | } 210 | }, 211 | "EcsFrontendAppTask": { 212 | "Condition": "DoDeployExampleApp", 213 | "Type": "AWS::ECS::TaskDefinition", 214 | "Properties": { 215 | "ContainerDefinitions": [ 216 | { 217 | "PortMappings": [ 218 | { 219 | "HostPort": 80, 220 | "ContainerPort": 9090 221 | } 222 | ], 223 | "Essential": true, 224 | "Name": "identiorca", 225 | "Image": "errordeveloper/identiorca", 226 | "Environment": [ 227 | { 228 | "Name": "USE_IP_ADDR", 229 | "Value": "yes" 230 | } 231 | ], 232 | "Cpu": 10, 233 | "Memory": 300 234 | }, 235 | { 236 | "Essential": true, 237 | "Name": "dnmonster", 238 | "Image": "amouat/dnmonster:1.0", 239 | "Cpu": 10, 240 | "Memory": 300 241 | } 242 | ], 243 | "Volumes": [] 244 | } 245 | }, 246 | "EcsFrontendAppService": { 247 | "Condition": "DoDeployExampleApp", 248 | "Type": "AWS::ECS::Service", 249 | "Properties": { 250 | "Cluster": { 251 | "Ref": "EcsCluster" 252 | }, 253 | "DesiredCount": { 254 | "Ref": "Scale" 255 | }, 256 | "TaskDefinition": { 257 | "Ref": "EcsFrontendAppTask" 258 | } 259 | } 260 | }, 261 | "Vpc": { 262 | "Type": "AWS::EC2::VPC", 263 | "Properties": { 264 | "CidrBlock": { 265 | "Fn::FindInMap": [ 266 | "VpcCidrs", 267 | "vpc", 268 | "cidr" 269 | ] 270 | } 271 | } 272 | }, 273 | "PubSubnetAz1": { 274 | "Type": "AWS::EC2::Subnet", 275 | "Properties": { 276 | "VpcId": { 277 | "Ref": "Vpc" 278 | }, 279 | "CidrBlock": { 280 | "Fn::FindInMap": [ 281 | "VpcCidrs", 282 | "pubsubnet1", 283 | "cidr" 284 | ] 285 | }, 286 | "AvailabilityZone": { 287 | "Fn::Select": [ 288 | "0", 289 | { 290 | "Fn::GetAZs": { 291 | "Ref": "AWS::Region" 292 | } 293 | } 294 | ] 295 | } 296 | } 297 | }, 298 | "PubSubnetAz2": { 299 | "Type": "AWS::EC2::Subnet", 300 | "Properties": { 301 | "VpcId": { 302 | "Ref": "Vpc" 303 | }, 304 | "CidrBlock": { 305 | "Fn::FindInMap": [ 306 | "VpcCidrs", 307 | "pubsubnet2", 308 | "cidr" 309 | ] 310 | }, 311 | "AvailabilityZone": { 312 | "Fn::Select": [ 313 | "1", 314 | { 315 | "Fn::GetAZs": { 316 | "Ref": "AWS::Region" 317 | } 318 | } 319 | ] 320 | } 321 | } 322 | }, 323 | "InternetGateway": { 324 | "Type": "AWS::EC2::InternetGateway" 325 | }, 326 | "AttachGateway": { 327 | "Type": "AWS::EC2::VPCGatewayAttachment", 328 | "Properties": { 329 | "VpcId": { 330 | "Ref": "Vpc" 331 | }, 332 | "InternetGatewayId": { 333 | "Ref": "InternetGateway" 334 | } 335 | } 336 | }, 337 | "RouteViaIgw": { 338 | "Type": "AWS::EC2::RouteTable", 339 | "Properties": { 340 | "VpcId": { 341 | "Ref": "Vpc" 342 | } 343 | } 344 | }, 345 | "PublicRouteViaIgw": { 346 | "DependsOn": "AttachGateway", 347 | "Type": "AWS::EC2::Route", 348 | "Properties": { 349 | "RouteTableId": { 350 | "Ref": "RouteViaIgw" 351 | }, 352 | "DestinationCidrBlock": "0.0.0.0/0", 353 | "GatewayId": { 354 | "Ref": "InternetGateway" 355 | } 356 | } 357 | }, 358 | "PubSubnet1RouteTableAssociation": { 359 | "Type": "AWS::EC2::SubnetRouteTableAssociation", 360 | "Properties": { 361 | "SubnetId": { 362 | "Ref": "PubSubnetAz1" 363 | }, 364 | "RouteTableId": { 365 | "Ref": "RouteViaIgw" 366 | } 367 | } 368 | }, 369 | "PubSubnet2RouteTableAssociation": { 370 | "Type": "AWS::EC2::SubnetRouteTableAssociation", 371 | "Properties": { 372 | "SubnetId": { 373 | "Ref": "PubSubnetAz2" 374 | }, 375 | "RouteTableId": { 376 | "Ref": "RouteViaIgw" 377 | } 378 | } 379 | }, 380 | "EcsSecurityGroup": { 381 | "Type": "AWS::EC2::SecurityGroup", 382 | "Properties": { 383 | "GroupDescription": "ECS Allowed Ports", 384 | "VpcId": { 385 | "Ref": "Vpc" 386 | } 387 | } 388 | }, 389 | "EcsSecurityGroupIngressAppPort": { 390 | "Type": "AWS::EC2::SecurityGroupIngress", 391 | "Properties": { 392 | "GroupId": { 393 | "Ref": "EcsSecurityGroup" 394 | }, 395 | "IpProtocol": "tcp", 396 | "FromPort": "80", 397 | "ToPort": "80", 398 | "CidrIp": "0.0.0.0/0" 399 | } 400 | }, 401 | "EcsSecurityGroupIngressSshPort": { 402 | "Type": "AWS::EC2::SecurityGroupIngress", 403 | "Properties": { 404 | "GroupId": { 405 | "Ref": "EcsSecurityGroup" 406 | }, 407 | "IpProtocol": "tcp", 408 | "FromPort": "22", 409 | "ToPort": "22", 410 | "CidrIp": "0.0.0.0/0" 411 | } 412 | }, 413 | "EcsSecurityGroupIngressWeaveScopeExtPort": { 414 | "Type": "AWS::EC2::SecurityGroupIngress", 415 | "Properties": { 416 | "GroupId": { 417 | "Ref": "EcsSecurityGroup" 418 | }, 419 | "IpProtocol": "tcp", 420 | "FromPort": "4040", 421 | "ToPort": "4040", 422 | "CidrIp": "0.0.0.0/0" 423 | } 424 | }, 425 | "EcsSecurityGroupIngressWeaveScopeIntPort": { 426 | "Type": "AWS::EC2::SecurityGroupIngress", 427 | "Properties": { 428 | "GroupId": { 429 | "Ref": "EcsSecurityGroup" 430 | }, 431 | "IpProtocol": "tcp", 432 | "FromPort": "4040", 433 | "ToPort": "4040", 434 | "SourceSecurityGroupId": { 435 | "Ref": "EcsSecurityGroup" 436 | } 437 | } 438 | }, 439 | "EcsSecurityGroupIngressWeaveNetIntTcpPort": { 440 | "Type": "AWS::EC2::SecurityGroupIngress", 441 | "Properties": { 442 | "GroupId": { 443 | "Ref": "EcsSecurityGroup" 444 | }, 445 | "IpProtocol": "tcp", 446 | "FromPort": "6783", 447 | "ToPort": "6783", 448 | "SourceSecurityGroupId": { 449 | "Ref": "EcsSecurityGroup" 450 | } 451 | } 452 | }, 453 | "EcsSecurityGroupIngressWeaveNetIntUdpPorts": { 454 | "Type": "AWS::EC2::SecurityGroupIngress", 455 | "Properties": { 456 | "GroupId": { 457 | "Ref": "EcsSecurityGroup" 458 | }, 459 | "IpProtocol": "udp", 460 | "FromPort": "6783", 461 | "ToPort": "6784", 462 | "SourceSecurityGroupId": { 463 | "Ref": "EcsSecurityGroup" 464 | } 465 | } 466 | }, 467 | "EcsInstancePolicy": { 468 | "Type": "AWS::IAM::Role", 469 | "Properties": { 470 | "AssumeRolePolicyDocument": { 471 | "Version": "2012-10-17", 472 | "Statement": [ 473 | { 474 | "Effect": "Allow", 475 | "Principal": { 476 | "Service": [ 477 | "ec2.amazonaws.com" 478 | ] 479 | }, 480 | "Action": [ 481 | "sts:AssumeRole" 482 | ] 483 | } 484 | ] 485 | }, 486 | "Path": "/", 487 | "ManagedPolicyArns": [ 488 | "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" 489 | ], 490 | "Policies": [ 491 | { 492 | "PolicyName": "ClusterInstanceRole", 493 | "PolicyDocument": { 494 | "Version": "2012-10-17", 495 | "Statement": [ 496 | { 497 | "Effect": "Allow", 498 | "Action": [ 499 | "ecs:CreateCluster", 500 | "ecs:DeregisterContainerInstance", 501 | "ecs:DiscoverPollEndpoint", 502 | "ecs:Poll", 503 | "ecs:RegisterContainerInstance", 504 | "ecs:Submit*", 505 | "ecs:ListClusters", 506 | "ecs:ListContainerInstances", 507 | "ecs:DescribeContainerInstances", 508 | "ecs:ListServices", 509 | "ecs:DescribeTasks", 510 | "ecs:DescribeServices", 511 | "ec2:DescribeInstances", 512 | "ec2:DescribeTags", 513 | "autoscaling:DescribeAutoScalingInstances" 514 | ], 515 | "Resource": [ 516 | "*" 517 | ] 518 | } 519 | ] 520 | } 521 | } 522 | ] 523 | } 524 | }, 525 | "EcsInstanceProfile": { 526 | "Type": "AWS::IAM::InstanceProfile", 527 | "Properties": { 528 | "Path": "/", 529 | "Roles": [ 530 | { 531 | "Ref": "EcsInstancePolicy" 532 | } 533 | ] 534 | } 535 | }, 536 | "EcsInstanceLc": { 537 | "Type": "AWS::AutoScaling::LaunchConfiguration", 538 | "Properties": { 539 | "ImageId": { 540 | "Fn::FindInMap": [ 541 | "WeaveworksEcsAmiIds", 542 | { 543 | "Ref": "AWS::Region" 544 | }, 545 | "ImageId" 546 | ] 547 | }, 548 | "InstanceType": { 549 | "Ref": "EcsInstanceType" 550 | }, 551 | "AssociatePublicIpAddress": true, 552 | "IamInstanceProfile": { 553 | "Ref": "EcsInstanceProfile" 554 | }, 555 | "KeyName": { 556 | "Ref": "KeyName" 557 | }, 558 | "SecurityGroups": [ 559 | { 560 | "Ref": "EcsSecurityGroup" 561 | } 562 | ], 563 | "UserData": { 564 | "Fn::Base64": { 565 | "Fn::Join": [ 566 | "\n", 567 | [ 568 | "#!/bin/bash -ex", 569 | "yum install -y aws-cfn-bootstrap", 570 | { 571 | "Fn::Join": [ 572 | " ", 573 | [ 574 | "/opt/aws/bin/cfn-init", 575 | "--verbose", 576 | "--stack", 577 | { 578 | "Ref": "AWS::StackName" 579 | }, 580 | "--region", 581 | { 582 | "Ref": "AWS::Region" 583 | }, 584 | "--resource", 585 | "EcsInstanceLc" 586 | ] 587 | ] 588 | } 589 | ] 590 | ] 591 | } 592 | } 593 | }, 594 | "Metadata": { 595 | "AWS::CloudFormation::Init": { 596 | "config": { 597 | "packages": { 598 | "yum": { 599 | "jq": [] 600 | }, 601 | "python": { 602 | "awscli": [] 603 | } 604 | }, 605 | "files": { 606 | "/etc/ecs/ecs.config": { 607 | "content": { 608 | "Fn::Join": [ 609 | "", 610 | [ 611 | "ECS_CLUSTER=", 612 | { 613 | "Ref": "EcsCluster" 614 | } 615 | ] 616 | ] 617 | } 618 | }, 619 | "/etc/weave/scope.config": { 620 | "content": { 621 | "Fn::Join": [ 622 | "", 623 | [ 624 | { 625 | "Fn::If": [ 626 | "UseWeaveScopeStandalone", 627 | "## SERVICE_TOKEN=", 628 | "SERVICE_TOKEN=" 629 | ] 630 | }, 631 | { 632 | "Fn::If": [ 633 | "UseWeaveScopeStandalone", 634 | "", 635 | { 636 | "Ref": "WeaveCloudServiceToken" 637 | } 638 | ] 639 | } 640 | ] 641 | ] 642 | } 643 | }, 644 | "/etc/init/ecs.override": { 645 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/ecs.override" 646 | }, 647 | "/etc/init/weave.conf": { 648 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/weave.conf" 649 | }, 650 | "/etc/init/scope.conf": { 651 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/scope.conf" 652 | }, 653 | "/etc/weave/run.sh": { 654 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/run.sh", 655 | "mode": "000755" 656 | }, 657 | "/etc/weave/peers.sh": { 658 | "source": "https://raw.github.com/weaveworks/integrations/master/aws/ecs/packer/to-upload/peers.sh", 659 | "mode": "000755" 660 | }, 661 | "/usr/local/bin/weave": { 662 | "source": { 663 | "Fn::Join": [ 664 | "/", 665 | [ 666 | "https://github.com/weaveworks/weave/releases/download", 667 | "v2.0.4", 668 | "weave" 669 | ] 670 | ] 671 | }, 672 | "mode": "000755" 673 | }, 674 | "/usr/local/bin/scope": { 675 | "source": { 676 | "Fn::Join": [ 677 | "/", 678 | [ 679 | "https://github.com/weaveworks/scope/releases/download", 680 | "v1.6.4", 681 | "scope" 682 | ] 683 | ] 684 | }, 685 | "mode": "000755" 686 | } 687 | } 688 | } 689 | } 690 | } 691 | }, 692 | "EcsInstanceAsg": { 693 | "Type": "AWS::AutoScaling::AutoScalingGroup", 694 | "Properties": { 695 | "VPCZoneIdentifier": [ 696 | { 697 | "Fn::Join": [ 698 | ",", 699 | [ 700 | { 701 | "Ref": "PubSubnetAz1" 702 | }, 703 | { 704 | "Ref": "PubSubnetAz2" 705 | } 706 | ] 707 | ] 708 | } 709 | ], 710 | "LaunchConfigurationName": { 711 | "Ref": "EcsInstanceLc" 712 | }, 713 | "MinSize": "1", 714 | "MaxSize": { 715 | "Ref": "Scale" 716 | }, 717 | "DesiredCapacity": { 718 | "Ref": "Scale" 719 | }, 720 | "LoadBalancerNames": [ 721 | { 722 | "Ref": "EcsFrontendElasticLoadBalancing" 723 | } 724 | ], 725 | "Tags": [ 726 | { 727 | "Key": "Name", 728 | "Value": { 729 | "Fn::Join": [ 730 | "", 731 | [ 732 | "ECS Instance - ", 733 | { 734 | "Ref": "AWS::StackName" 735 | } 736 | ] 737 | ] 738 | }, 739 | "PropagateAtLaunch": "true" 740 | } 741 | ] 742 | } 743 | }, 744 | "EcsFrontendElasticLoadBalancing": { 745 | "Type": "AWS::ElasticLoadBalancing::LoadBalancer", 746 | "DependsOn": "InternetGateway", 747 | "Properties": { 748 | "Listeners": [ 749 | { 750 | "Fn::If": [ 751 | "DoDeployExampleApp", 752 | { 753 | "InstancePort": "80", 754 | "LoadBalancerPort": "80", 755 | "InstanceProtocol": "HTTP", 756 | "Protocol": "HTTP" 757 | }, 758 | { 759 | "Ref": "AWS::NoValue" 760 | } 761 | ] 762 | }, 763 | { 764 | "Fn::If": [ 765 | "UseWeaveScopeStandalone", 766 | { 767 | "InstancePort": "4040", 768 | "LoadBalancerPort": "4040", 769 | "InstanceProtocol": "TCP", 770 | "Protocol": "TCP" 771 | }, 772 | { 773 | "Ref": "AWS::NoValue" 774 | } 775 | ] 776 | } 777 | ], 778 | "SecurityGroups": [ 779 | { 780 | "Ref": "EcsSecurityGroup" 781 | } 782 | ], 783 | "Subnets": [ 784 | { 785 | "Ref": "PubSubnetAz1" 786 | }, 787 | { 788 | "Ref": "PubSubnetAz2" 789 | } 790 | ] 791 | } 792 | } 793 | } 794 | } 795 | --------------------------------------------------------------------------------