├── .gitignore ├── Gemfile ├── terraform └── ec2 │ ├── tf-files │ ├── main.tf │ ├── userdata.tpl │ ├── debug-security-group.tf │ ├── variables.tf │ ├── vpc.tf │ └── yocto.tf │ └── ci │ ├── delete.sh │ ├── integration-test.sh │ └── pipeline.sh ├── 4cheaters ├── terraform │ └── tf-files │ │ ├── userdata.tpl │ │ ├── main.tf │ │ ├── debug-security-group.tf │ │ ├── variables.tf │ │ ├── vpc.tf │ │ └── yocto.tf └── cloudformation │ ├── ec2 │ └── cf-templates │ │ ├── vpc-debug-security-group.yaml │ │ ├── vpc.yaml │ │ └── vpc-yocto.yaml │ ├── lambda │ ├── ci │ │ ├── deleteStacks.sh │ │ ├── integration-test.sh │ │ └── pipeline.sh │ └── cf-templates │ │ ├── chat-resources.yaml │ │ ├── helloworld.yaml │ │ ├── chat-read.yaml │ │ ├── chat-write.yaml │ │ └── chat-api.yaml │ └── fargate │ └── cf-templates │ ├── resources.yaml │ ├── vpc.yaml │ └── service.yaml ├── cloudformation ├── ec2 │ ├── properties │ │ ├── yocto.yaml │ │ └── vpc.yaml │ ├── ci │ │ ├── integration-test.sh │ │ ├── deleteStacks.sh │ │ └── pipeline.sh │ ├── cf-templates │ │ ├── vpc-debug-security-group.yaml │ │ ├── vpc.yaml │ │ └── vpc-yocto.yaml │ └── jmeter │ │ └── yocto.jmx ├── lambda │ ├── cf-templates │ │ ├── chat-write.yaml │ │ ├── chat-resources.yaml │ │ ├── helloworld.yaml │ │ ├── chat-read.yaml │ │ └── chat-api.yaml │ └── ci │ │ ├── deleteStacks.sh │ │ ├── integration-test.sh │ │ └── pipeline.sh └── fargate │ ├── properties │ └── vpc.yaml │ ├── ci │ ├── integration-test.sh │ ├── deleteStacks.sh │ └── pipeline.sh │ ├── cf-templates │ ├── service.yaml │ ├── vpc.yaml │ └── resources.yaml │ └── jmeter │ └── yocto.jmx ├── .igor.sh ├── Gemfile.lock ├── Dockerfile ├── igor.sh └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | jmeter.log 3 | *tfstate* 4 | .terraform 5 | plan.out 6 | *.tfvars 7 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'aws-sdk', '~> 2.5', '>= 2.5.1' 4 | gem 'autostacker24', '>=2.7.0' 5 | -------------------------------------------------------------------------------- /terraform/ec2/tf-files/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "${var.region}" 3 | profile = "${var.profile}" 4 | } 5 | -------------------------------------------------------------------------------- /terraform/ec2/tf-files/userdata.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | yum install -y docker 3 | /etc/init.d/docker start 4 | docker run -dp 8080:8080 felixb/yocto-httpd 5 | -------------------------------------------------------------------------------- /4cheaters/terraform/tf-files/userdata.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | yum install -y docker 3 | /etc/init.d/docker start 4 | docker run -dp 8080:8080 felixb/yocto-httpd 5 | -------------------------------------------------------------------------------- /cloudformation/ec2/properties/yocto.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | VPCStackName: "vpc-foobar" 3 | TeamName: "foobar" 4 | KeyName: "some-keypair" 5 | ImageId: "ami-82be18ed" 6 | -------------------------------------------------------------------------------- /4cheaters/terraform/tf-files/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "${var.region}" 3 | profile = "${var.profile}" 4 | } 5 | 6 | data "aws_availability_zones" "current" {} 7 | -------------------------------------------------------------------------------- /cloudformation/lambda/cf-templates/chat-write.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | 4 | Parameters: 5 | TeamName: 6 | Type: String 7 | 8 | Resources: 9 | -------------------------------------------------------------------------------- /terraform/ec2/ci/delete.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | SCRIPT_DIR="$(cd "$(dirname "$0")" ; pwd -P)" 6 | 7 | pushd "${SCRIPT_DIR}/../tf-files" > /dev/null 8 | 9 | terraform destroy -force 10 | 11 | popd > /dev/null 12 | -------------------------------------------------------------------------------- /cloudformation/ec2/properties/vpc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | TeamName: "foobar" 3 | DnsRootDomain: "DNS_ROOT_DOMAIN" 4 | VpcCidr: "172.16.0.0/16" 5 | VpcSubnet1Cidr: "172.16.0.0/21" 6 | VpcSubnet2Cidr: "172.16.8.0/21" 7 | VpcSubnet3Cidr: "172.16.16.0/21" 8 | -------------------------------------------------------------------------------- /cloudformation/fargate/properties/vpc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | TeamName: "foobar" 3 | DnsRootDomain: "DNS_ROOT_DOMAIN" 4 | VpcCidr: "172.16.0.0/16" 5 | VpcSubnet1Cidr: "172.16.0.0/21" 6 | VpcSubnet2Cidr: "172.16.8.0/21" 7 | VpcSubnet3Cidr: "172.16.16.0/21" 8 | -------------------------------------------------------------------------------- /.igor.sh: -------------------------------------------------------------------------------- 1 | IGOR_DOCKER_IMAGE=felixb/aws-codelab 2 | IGOR_DOCKER_COMMAND=/bin/bash 3 | IGOR_DOCKER_RM=1 4 | IGOR_DOCKER_TTY=1 5 | IGOR_DOCKER_USER=$(id -u) 6 | IGOR_DOCKER_GROUP=$(id -g) 7 | IGOR_PORTS='3000' 8 | IGOR_MOUNT_PASSWD=1 9 | IGOR_MOUNT_GROUP=1 10 | IGOR_MOUNTS_RW="${HOME}/.aws" 11 | -------------------------------------------------------------------------------- /4cheaters/terraform/tf-files/debug-security-group.tf: -------------------------------------------------------------------------------- 1 | resource "aws_security_group" "debugsecuritygroup" { 2 | name = "Allow SSH Traffic" 3 | vpc_id = "${aws_vpc.vpc.id}" 4 | 5 | ingress { 6 | from_port = 22 7 | protocol = "tcp" 8 | to_port = 22 9 | cidr_blocks = ["0.0.0.0/0"] 10 | } 11 | } -------------------------------------------------------------------------------- /terraform/ec2/tf-files/debug-security-group.tf: -------------------------------------------------------------------------------- 1 | // 2. Deploy debug security group 2 | //resource "aws_security_group" "debugsecuritygroup" { 3 | // name = "Allow SSH Traffic" 4 | // vpc_id = "${aws_vpc.vpc.id}" 5 | // 6 | // ingress { 7 | // from_port = 22 8 | // protocol = "tcp" 9 | // to_port = 22 10 | // cidr_blocks = ["0.0.0.0/0"] 11 | // } 12 | //} -------------------------------------------------------------------------------- /terraform/ec2/ci/integration-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | if [ -z "${YOCTO_URL}" ]; then 6 | echo "Please set environment variable YOCTO_URL" 7 | exit 1 8 | fi 9 | 10 | echo -e "\nTry to fetch important information .." 11 | curl -s "http://${YOCTO_URL}" 12 | success=$? 13 | if [ ${success} -eq 0 ]; then 14 | echo -e "\nSuccessful .." 15 | else 16 | echo -e "\nFailed .." 17 | exit 2 18 | fi 19 | -------------------------------------------------------------------------------- /cloudformation/ec2/ci/integration-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | if [ -z "${YOCTO_URL}" ]; then 6 | echo "Please set environment variable YOCTO_URL" 7 | exit 1 8 | fi 9 | 10 | echo -e "\nTry to fetch important information .." 11 | curl -s "http://${YOCTO_URL}" 12 | success=$? 13 | if [ ${success} -eq 0 ]; then 14 | echo -e "\nSuccessful .." 15 | else 16 | echo -e "\nFailed .." 17 | exit 2 18 | fi 19 | -------------------------------------------------------------------------------- /cloudformation/fargate/ci/integration-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | if [ -z "${YOCTO_URL}" ]; then 6 | echo "Please set environment variable YOCTO_URL" 7 | exit 1 8 | fi 9 | 10 | echo -e "\nTry to fetch important information .." 11 | curl -s "http://${YOCTO_URL}" 12 | success=$? 13 | if [ ${success} -eq 0 ]; then 14 | echo -e "\nSuccessful .." 15 | else 16 | echo -e "\nFailed .." 17 | exit 2 18 | fi 19 | -------------------------------------------------------------------------------- /4cheaters/terraform/tf-files/variables.tf: -------------------------------------------------------------------------------- 1 | variable "profile" { 2 | type = "string" 3 | } 4 | 5 | variable "region" { 6 | type = "string" 7 | default = "eu-central-1" 8 | } 9 | 10 | variable "vpc_cidr" { 11 | type = "string" 12 | default = "172.16.0.0/16" 13 | } 14 | 15 | variable "team_name" { 16 | type = "string" 17 | } 18 | 19 | variable "ami_id" { 20 | type = "string" 21 | } 22 | 23 | variable "instance_type" { 24 | type = "string" 25 | default = "t2.nano" 26 | } 27 | 28 | variable "sshkeyname" { 29 | type = "string" 30 | } -------------------------------------------------------------------------------- /terraform/ec2/tf-files/variables.tf: -------------------------------------------------------------------------------- 1 | variable "profile" { 2 | type = "string" 3 | } 4 | 5 | variable "region" { 6 | type = "string" 7 | } 8 | 9 | variable "azs" { 10 | type = "list" 11 | } 12 | 13 | variable "vpc_cidr" { 14 | type = "string" 15 | } 16 | 17 | variable "subnet_cidrs" { 18 | type = "list" 19 | } 20 | 21 | variable "team_name" { 22 | type = "string" 23 | } 24 | 25 | variable "ami_id" { 26 | type = "string" 27 | } 28 | 29 | variable "instance_type" { 30 | type = "string" 31 | } 32 | 33 | variable "sshkeyname" { 34 | type = "string" 35 | } 36 | -------------------------------------------------------------------------------- /cloudformation/fargate/ci/deleteStacks.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | if [ -z "${PROFILE}" ]; then 6 | echo "Please set environment variable PROFILE" 7 | exit 1 8 | fi 9 | 10 | if [ -z "${TEAM_NAME}" ]; then 11 | echo "Please set environment variable TEAM_NAME" 12 | exit 1 13 | fi 14 | 15 | bundle exec autostacker24 delete --stack "${TEAM_NAME}-yocto" --profile "${PROFILE}" 16 | bundle exec autostacker24 delete --stack "${TEAM_NAME}-resources" --profile "${PROFILE}" 17 | bundle exec autostacker24 delete --stack "${TEAM_NAME}-vpc" --profile "${PROFILE}" 18 | -------------------------------------------------------------------------------- /cloudformation/ec2/ci/deleteStacks.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | if [ -z "${PROFILE}" ]; then 6 | echo "Please set environment variable PROFILE" 7 | exit 1 8 | fi 9 | 10 | if [ -z "${TEAM_NAME}" ]; then 11 | echo "Please set environment variable TEAM_NAME" 12 | exit 1 13 | fi 14 | 15 | bundle exec autostacker24 delete --stack "vpc-${TEAM_NAME}-yocto" --profile "${PROFILE}" 16 | bundle exec autostacker24 delete --stack "vpc-${TEAM_NAME}-debug-sg" --profile "${PROFILE}" 17 | bundle exec autostacker24 delete --stack "vpc-${TEAM_NAME}" --profile "${PROFILE}" 18 | -------------------------------------------------------------------------------- /terraform/ec2/ci/pipeline.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | SCRIPT_DIR="$(cd "$(dirname "$0")" ; pwd -P)" 6 | 7 | pushd "${SCRIPT_DIR}/../tf-files" > /dev/null 8 | 9 | terraform init \ 10 | -input=false 11 | 12 | terraform plan \ 13 | -input=false \ 14 | -out plan.out 15 | 16 | terraform apply \ 17 | -input=false \ 18 | plan.out 19 | 20 | # Run integration tests if YOCTO_URL present 21 | if [ -n "${YOCTO_URL}" ]; then 22 | echo -e "\nStarting integration tests .." 23 | ./ci/integration-test.sh 24 | else 25 | echo -e "\nSet YOCTO_URL to run integration tests" 26 | fi 27 | 28 | popd > /dev/null 29 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | autostacker24 (2.7.0) 5 | aws-sdk-core (~> 2) 6 | json (~> 2.0) 7 | json_pure (~> 2.0) 8 | aws-sdk (2.10.34) 9 | aws-sdk-resources (= 2.10.34) 10 | aws-sdk-core (2.10.34) 11 | aws-sigv4 (~> 1.0) 12 | jmespath (~> 1.0) 13 | aws-sdk-resources (2.10.34) 14 | aws-sdk-core (= 2.10.34) 15 | aws-sigv4 (1.0.1) 16 | jmespath (1.3.1) 17 | json (2.3.1) 18 | json_pure (2.1.0) 19 | 20 | PLATFORMS 21 | ruby 22 | 23 | DEPENDENCIES 24 | autostacker24 (>= 2.7.0) 25 | aws-sdk (~> 2.5, >= 2.5.1) 26 | 27 | BUNDLED WITH 28 | 1.15.3 29 | -------------------------------------------------------------------------------- /cloudformation/ec2/cf-templates/vpc-debug-security-group.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: "2010-09-09" 3 | 4 | Parameters: 5 | VPCStackName: 6 | Type: String 7 | TeamName: 8 | Type: String 9 | 10 | Resources: 11 | 12 | DebugSecurityGroup: 13 | Type: AWS::EC2::SecurityGroup 14 | Properties: 15 | GroupDescription: "Allow ssh access through instance" 16 | VpcId: !ImportValue {"Fn::Sub": "${VPCStackName}-vpc-id"} 17 | SecurityGroupIngress: 18 | - IpProtocol: tcp 19 | FromPort: "22" 20 | ToPort: "22" 21 | CidrIp: "0.0.0.0/0" 22 | Tags: 23 | - Key: Name 24 | Value: !Sub "${TeamName}-ssh-debug" 25 | -------------------------------------------------------------------------------- /cloudformation/lambda/ci/deleteStacks.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ -z "${PROFILE}" ]; then 4 | echo "Please set environment variable PROFILE" 5 | exit 1 6 | fi 7 | 8 | if [ -z "${TEAM_NAME}" ]; then 9 | echo "Please set environment variable TEAM_NAME" 10 | exit 1 11 | fi 12 | 13 | bundle exec autostacker24 delete --stack "lambda-chat-${TEAM_NAME}-api" --profile "${PROFILE}" 14 | bundle exec autostacker24 delete --stack "lambda-chat-${TEAM_NAME}-read" --profile "${PROFILE}" 15 | bundle exec autostacker24 delete --stack "lambda-chat-${TEAM_NAME}-write" --profile "${PROFILE}" 16 | bundle exec autostacker24 delete --stack "lambda-chat-${TEAM_NAME}-resources" --profile "${PROFILE}" 17 | -------------------------------------------------------------------------------- /4cheaters/cloudformation/ec2/cf-templates/vpc-debug-security-group.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: "2010-09-09" 3 | 4 | Parameters: 5 | VPCStackName: 6 | Type: String 7 | TeamName: 8 | Type: String 9 | 10 | Resources: 11 | 12 | DebugSecurityGroup: 13 | Type: AWS::EC2::SecurityGroup 14 | Properties: 15 | GroupDescription: "Allow ssh access through instance" 16 | VpcId: !ImportValue {"Fn::Sub": "${VPCStackName}-vpc-id"} 17 | SecurityGroupIngress: 18 | - IpProtocol: tcp 19 | FromPort: "22" 20 | ToPort: "22" 21 | CidrIp: "0.0.0.0/0" 22 | Tags: 23 | - Key: Name 24 | Value: !Sub "${TeamName}-ssh-debug" 25 | -------------------------------------------------------------------------------- /4cheaters/cloudformation/lambda/ci/deleteStacks.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ -z "${PROFILE}" ]; then 4 | echo "Please set environment variable PROFILE" 5 | exit 1 6 | fi 7 | 8 | if [ -z "${TEAM_NAME}" ]; then 9 | echo "Please set environment variable TEAM_NAME" 10 | exit 1 11 | fi 12 | 13 | bundle exec autostacker24 delete --stack "lambda-chat-${TEAM_NAME}-api" --profile "${PROFILE}" 14 | bundle exec autostacker24 delete --stack "lambda-chat-${TEAM_NAME}-read" --profile "${PROFILE}" 15 | bundle exec autostacker24 delete --stack "lambda-chat-${TEAM_NAME}-write" --profile "${PROFILE}" 16 | bundle exec autostacker24 delete --stack "lambda-chat-${TEAM_NAME}-resources" --profile "${PROFILE}" 17 | -------------------------------------------------------------------------------- /cloudformation/lambda/cf-templates/chat-resources.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | 4 | Parameters: 5 | TeamName: 6 | Type: String 7 | 8 | Resources: 9 | 10 | ChatDynamoDb: 11 | Type: AWS::DynamoDB::Table 12 | Properties: 13 | TableName: !Sub "${TeamName}-chat" 14 | AttributeDefinitions: 15 | - AttributeName: "timestamp" 16 | AttributeType: "N" 17 | - AttributeName: "username" 18 | AttributeType: "S" 19 | KeySchema: 20 | - AttributeName: "timestamp" 21 | KeyType: "HASH" 22 | - AttributeName: "username" 23 | KeyType: "RANGE" 24 | ProvisionedThroughput: 25 | ReadCapacityUnits: 5 26 | WriteCapacityUnits: 1 27 | -------------------------------------------------------------------------------- /4cheaters/cloudformation/lambda/cf-templates/chat-resources.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | 4 | Parameters: 5 | TeamName: 6 | Type: String 7 | 8 | Resources: 9 | 10 | ChatDynamoDb: 11 | Type: AWS::DynamoDB::Table 12 | Properties: 13 | TableName: !Sub "${TeamName}-chat" 14 | AttributeDefinitions: 15 | - AttributeName: "timestamp" 16 | AttributeType: "N" 17 | - AttributeName: "username" 18 | AttributeType: "S" 19 | KeySchema: 20 | - AttributeName: "timestamp" 21 | KeyType: "HASH" 22 | - AttributeName: "username" 23 | KeyType: "RANGE" 24 | ProvisionedThroughput: 25 | ReadCapacityUnits: 5 26 | WriteCapacityUnits: 1 27 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:17.04 2 | 3 | # building a docker images meant to run with igor 4 | # the image provieds all tools required for the code lab: aws cli, autostacker24, cli53 5 | # run the following command to build the image locally: 6 | # docker build -t felixb/aws-codelab . 7 | 8 | CMD ["/bin/bash"] 9 | 10 | ENV \ 11 | CLI53_VERSION=0.8.7 \ 12 | AUTOSTACKER_VERSION=2.7.0 \ 13 | NODE_VERSION=6.x 14 | 15 | RUN apt-get update \ 16 | && apt-get install -y awscli ruby ruby-dev gcc make curl tree vim \ 17 | && rm -rf /var/lib/apt/* /var/cache/apt/* 18 | 19 | RUN gem install -v ${AUTOSTACKER_VERSION} autostacker24 20 | 21 | RUN curl -L -o /usr/local/bin/cli53 https://github.com/barnybug/cli53/releases/download/${CLI53_VERSION}/cli53-linux-amd64 \ 22 | && chmod +x /usr/local/bin/cli53 23 | 24 | RUN curl -L -o /usr/local/bin/sniper http://lubia-me.qiniudn.com/sniper_linux_amd64 \ 25 | && chmod +x /usr/local/bin/sniper 26 | 27 | RUN curl -sL https://deb.nodesource.com/setup_${NODE_VERSION} | bash - \ 28 | && apt-get install nodejs \ 29 | && rm -rf /var/lib/apt/* /var/cache/apt/* 30 | -------------------------------------------------------------------------------- /cloudformation/lambda/ci/integration-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ -z "${API_GATEWAY_ID}" ]; then 4 | echo "Please set environment variable API_GATEWAY_ID" 5 | exit 1 6 | fi 7 | 8 | echo -e "\nReading messages .." 9 | responseCode=$(curl -sw '%{http_code}' "https://${API_GATEWAY_ID}.execute-api.eu-central-1.amazonaws.com/LATEST/chat" -o /dev/null) 10 | echo "ResponseCode: ${responseCode}" 11 | if [ ${responseCode} -eq 200 ]; then 12 | echo -e "Read messages successfully .." 13 | else 14 | echo -e "Reading messages failed .." 15 | exit 3 16 | fi 17 | 18 | echo -e "\nSending message .." 19 | responseCode=$(curl -XPOST \ 20 | -sw '%{http_code}' \ 21 | -d '{"username":"testuser","message": "test message"}' \ 22 | "https://${API_GATEWAY_ID}.execute-api.eu-central-1.amazonaws.com/LATEST/chat" \ 23 | -o /dev/null \ 24 | ) 25 | echo "ResponseCode: ${responseCode}" 26 | if [ ${responseCode} -eq 200 ]; then 27 | echo -e "Send message successfully .." 28 | else 29 | echo -e "Sending message failed .." 30 | exit 2 31 | fi 32 | -------------------------------------------------------------------------------- /4cheaters/cloudformation/lambda/ci/integration-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ -z "${API_GATEWAY_ID}" ]; then 4 | echo "Please set environment variable API_GATEWAY_ID" 5 | exit 1 6 | fi 7 | 8 | echo -e "\nReading messages .." 9 | responseCode=$(curl -sw '%{http_code}' "https://${API_GATEWAY_ID}.execute-api.eu-central-1.amazonaws.com/LATEST/chat" -o /dev/null) 10 | echo "ResponseCode: ${responseCode}" 11 | if [ ${responseCode} -eq 200 ]; then 12 | echo -e "Read messages successfully .." 13 | else 14 | echo -e "Reading messages failed .." 15 | exit 3 16 | fi 17 | 18 | echo -e "\nSending message .." 19 | responseCode=$(curl -XPOST \ 20 | -sw '%{http_code}' \ 21 | -d '{"username":"testuser","message": "test message"}' \ 22 | "https://${API_GATEWAY_ID}.execute-api.eu-central-1.amazonaws.com/LATEST/chat" \ 23 | -o /dev/null \ 24 | ) 25 | echo "ResponseCode: ${responseCode}" 26 | if [ ${responseCode} -eq 200 ]; then 27 | echo -e "Send message successfully .." 28 | else 29 | echo -e "Sending message failed .." 30 | exit 2 31 | fi 32 | -------------------------------------------------------------------------------- /terraform/ec2/tf-files/vpc.tf: -------------------------------------------------------------------------------- 1 | // 1. Deploy vpc 2 | resource "aws_vpc" "vpc" { 3 | cidr_block = "${var.vpc_cidr}" 4 | tags { 5 | Name = "${var.team_name}-vpc" 6 | } 7 | } 8 | 9 | resource "aws_subnet" "publicsubnets" { 10 | count = "${length(var.azs)}" 11 | cidr_block = "${cidrsubnet(aws_vpc.vpc.cidr_block, 5, count.index)}" 12 | vpc_id = "${aws_vpc.vpc.id}" 13 | availability_zone = "${element(var.azs, count.index)}" 14 | 15 | tags { 16 | Name = "${var.team_name}-${element(var.azs, count.index)}-sn" 17 | } 18 | } 19 | 20 | resource "aws_internet_gateway" "igw" { 21 | vpc_id = "${aws_vpc.vpc.id}" 22 | 23 | tags { 24 | Name = "${var.team_name}-ig" 25 | } 26 | } 27 | 28 | resource "aws_route_table" "routetable" { 29 | vpc_id = "${aws_vpc.vpc.id}" 30 | 31 | tags { 32 | Name = "${var.team_name}-rt" 33 | } 34 | } 35 | 36 | resource "aws_route" "routepublic" { 37 | depends_on = [ 38 | "aws_internet_gateway.igw" 39 | ] 40 | route_table_id = "${aws_route_table.routetable.id}" 41 | destination_cidr_block = "0.0.0.0/0" 42 | gateway_id = "${aws_internet_gateway.igw.id}" 43 | } 44 | 45 | resource "aws_route_table_association" "subnettopublic" { 46 | count = "${length(var.azs)}" 47 | route_table_id = "${aws_route_table.routetable.id}" 48 | subnet_id = "${element(aws_subnet.publicsubnets.*.id, count.index)}" 49 | } 50 | -------------------------------------------------------------------------------- /4cheaters/terraform/tf-files/vpc.tf: -------------------------------------------------------------------------------- 1 | resource "aws_vpc" "vpc" { 2 | cidr_block = "${var.vpc_cidr}" 3 | tags { 4 | Name = "${var.team_name}-vpc" 5 | } 6 | } 7 | 8 | resource "aws_subnet" "publicsubnets" { 9 | count = "${length(data.aws_availability_zones.current.names)}" 10 | cidr_block = "${cidrsubnet(aws_vpc.vpc.cidr_block, 5, count.index)}" 11 | vpc_id = "${aws_vpc.vpc.id}" 12 | availability_zone = "${element(data.aws_availability_zones.current.names, count.index)}" 13 | 14 | tags { 15 | Name = "${var.team_name}-${element(data.aws_availability_zones.current.names, count.index)}-sn" 16 | } 17 | } 18 | 19 | resource "aws_internet_gateway" "igw" { 20 | vpc_id = "${aws_vpc.vpc.id}" 21 | 22 | tags { 23 | Name = "${var.team_name}-ig" 24 | } 25 | } 26 | 27 | resource "aws_route_table" "routetable" { 28 | vpc_id = "${aws_vpc.vpc.id}" 29 | 30 | tags { 31 | Name = "${var.team_name}-rt" 32 | } 33 | } 34 | 35 | resource "aws_route" "routepublic" { 36 | depends_on = [ 37 | "aws_internet_gateway.igw" 38 | ] 39 | route_table_id = "${aws_route_table.routetable.id}" 40 | destination_cidr_block = "0.0.0.0/0" 41 | gateway_id = "${aws_internet_gateway.igw.id}" 42 | } 43 | 44 | resource "aws_route_table_association" "subnettopublic" { 45 | count = "${length(data.aws_availability_zones.current.names)}" 46 | route_table_id = "${aws_route_table.routetable.id}" 47 | subnet_id = "${element(aws_subnet.publicsubnets.*.id, count.index)}" 48 | } 49 | -------------------------------------------------------------------------------- /terraform/ec2/tf-files/yocto.tf: -------------------------------------------------------------------------------- 1 | // 3. Deploy yocto 2 | //resource "aws_security_group" "instance" { 3 | // name = "Allow access to instance" 4 | // vpc_id = "${aws_vpc.vpc.id}" 5 | // 6 | // ingress { 7 | // from_port = 8080 8 | // protocol = "tcp" 9 | // to_port = 8080 10 | // cidr_blocks = [ 11 | // "0.0.0.0/0"] 12 | // } 13 | // 14 | // egress { 15 | // from_port = 0 16 | // protocol = "-1" 17 | // to_port = 0 18 | // cidr_blocks = ["0.0.0.0/0"] 19 | // } 20 | // 21 | // tags { 22 | // Name = "${var.team_name}-yocto-instance-sg" 23 | // } 24 | //} 25 | // 26 | //data "template_file" "userdata" { 27 | // template = "${file("${path.module}/userdata.tpl")}" 28 | //} 29 | // 30 | //resource "aws_launch_configuration" "yoctolaunch" { 31 | // name_prefix = "${var.team_name}-" 32 | // image_id = "${var.ami_id}" 33 | // instance_type = "${var.instance_type}" 34 | // key_name = "${var.sshkeyname}" 35 | // user_data = "${data.template_file.userdata.rendered}" 36 | // security_groups = ["${aws_security_group.instance.id}"] 37 | // associate_public_ip_address = true 38 | // lifecycle { create_before_destroy = true } 39 | //} 40 | // 41 | //resource "aws_autoscaling_group" "yoctoautoscaling" { 42 | // name_prefix = "${var.team_name}-" 43 | // launch_configuration = "${aws_launch_configuration.yoctolaunch.id}" 44 | // max_size = 2 45 | // min_size = 1 46 | // desired_capacity = 1 47 | // vpc_zone_identifier = ["${aws_subnet.publicsubnets.*.id}"] 48 | // health_check_type = "ELB" 49 | // health_check_grace_period = 120 50 | // wait_for_capacity_timeout = "3m" 51 | // 52 | // lifecycle {create_before_destroy = true} 53 | // 54 | // tags = [ 55 | // { 56 | // key = "Name" 57 | // value = "${var.team_name}-yocto" 58 | // propagate_at_launch = true 59 | // } 60 | // ] 61 | //} -------------------------------------------------------------------------------- /cloudformation/lambda/cf-templates/helloworld.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # bundle exec autostacker24 update --template lambda/cf-templates/helloworld.yaml --stack lambda-helloworld-TEAM_NAME --param TeamName=TEAM_NAME 3 | # bundle exec autostacker24 delete --stack lambda-helloworld-TEAM_NAME 4 | AWSTemplateFormatVersion: '2010-09-09' 5 | 6 | Parameters: 7 | TeamName: 8 | Type: String 9 | 10 | Resources: 11 | 12 | LambdaRole: 13 | Type: AWS::IAM::Role 14 | Properties: 15 | AssumeRolePolicyDocument: 16 | Version: '2012-10-17' 17 | Statement: 18 | - Effect: "Allow" 19 | Principal: 20 | Service: 21 | - lambda.amazonaws.com 22 | Action: 23 | - sts:AssumeRole 24 | Path: "/" 25 | 26 | LambdaFunction: 27 | Type: AWS::Lambda::Function 28 | Properties: 29 | FunctionName: !Sub "helloworld-${TeamName}" 30 | MemorySize: "128" 31 | Timeout: "2" 32 | Role: 33 | Fn::GetAtt: [ LambdaRole , "Arn" ] 34 | Runtime: "nodejs6.10" 35 | Handler: "index.sendMessage" 36 | Code: 37 | ZipFile: > 38 | exports.sendMessage = function(event, context) { 39 | console.log("running code"); 40 | context.succeed("done"); 41 | }; 42 | 43 | CronEvent: 44 | Type: AWS::Events::Rule 45 | Properties: 46 | Name: !Sub "trigger-helloworld-${TeamName}" 47 | ScheduleExpression: cron(0/10 * * * ? *) 48 | Targets: 49 | - Arn: 50 | Fn::GetAtt: [ LambdaFunction , "Arn" ] 51 | Id: !Ref LambdaFunction 52 | 53 | LambdaInvokePermission: 54 | Type: AWS::Lambda::Permission 55 | Properties: 56 | Principal: events.amazonaws.com 57 | FunctionName: 58 | Fn::GetAtt: [ LambdaFunction ,"Arn" ] 59 | Action: "lambda:InvokeFunction" 60 | SourceArn: 61 | Fn::GetAtt: [ CronEvent , "Arn" ] 62 | -------------------------------------------------------------------------------- /4cheaters/cloudformation/lambda/cf-templates/helloworld.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # bundle exec autostacker24 update --template lambda/cf-templates/helloworld.yaml --stack lambda-helloworld-TEAM_NAME --param TeamName=TEAM_NAME 3 | # bundle exec autostacker24 delete --stack lambda-helloworld-TEAM_NAME 4 | AWSTemplateFormatVersion: '2010-09-09' 5 | 6 | Parameters: 7 | TeamName: 8 | Type: String 9 | 10 | Resources: 11 | 12 | LambdaRole: 13 | Type: AWS::IAM::Role 14 | Properties: 15 | AssumeRolePolicyDocument: 16 | Version: '2012-10-17' 17 | Statement: 18 | - Effect: "Allow" 19 | Principal: 20 | Service: 21 | - lambda.amazonaws.com 22 | Action: 23 | - sts:AssumeRole 24 | Path: "/" 25 | 26 | LambdaFunction: 27 | Type: AWS::Lambda::Function 28 | Properties: 29 | FunctionName: !Sub "helloworld-${TeamName}" 30 | MemorySize: "128" 31 | Timeout: "2" 32 | Role: 33 | Fn::GetAtt: [ LambdaRole , "Arn" ] 34 | Runtime: "nodejs6.10" 35 | Handler: "index.sendMessage" 36 | Code: 37 | ZipFile: > 38 | exports.sendMessage = function(event, context) { 39 | console.log("Hello " + event.name); 40 | context.succeed("done"); 41 | }; 42 | 43 | CronEvent: 44 | Type: AWS::Events::Rule 45 | Properties: 46 | Name: !Sub "trigger-helloworld-${TeamName}" 47 | ScheduleExpression: cron(0/10 * * * ? *) 48 | Targets: 49 | - Arn: 50 | Fn::GetAtt: [ LambdaFunction , "Arn" ] 51 | Id: !Ref LambdaFunction 52 | 53 | LambdaInvokePermission: 54 | Type: AWS::Lambda::Permission 55 | Properties: 56 | Principal: events.amazonaws.com 57 | FunctionName: 58 | Fn::GetAtt: [ LambdaFunction ,"Arn" ] 59 | Action: "lambda:InvokeFunction" 60 | SourceArn: 61 | Fn::GetAtt: [ CronEvent , "Arn" ] 62 | -------------------------------------------------------------------------------- /cloudformation/lambda/cf-templates/chat-read.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | 4 | Parameters: 5 | TeamName: 6 | Type: String 7 | 8 | Resources: 9 | 10 | LambdaReadChatRole: 11 | Type: AWS::IAM::Role 12 | Properties: 13 | Path: "/" 14 | AssumeRolePolicyDocument: 15 | Version: '2012-10-17' 16 | Statement: 17 | - Effect: "Allow" 18 | Principal: 19 | Service: 20 | - lambda.amazonaws.com 21 | Action: 22 | - sts:AssumeRole 23 | ManagedPolicyArns: 24 | - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" 25 | Policies: 26 | - PolicyName: "ApiGatewayLogsPolicy" 27 | PolicyDocument: 28 | Version: "2012-10-17" 29 | Statement: 30 | - Effect: "Allow" 31 | Action: 32 | - "dynamodb:BatchGetItem" 33 | - "dynamodb:GetItem" 34 | - "dynamodb:Scan" 35 | - "dynamodb:Query" 36 | Resource: "*" 37 | 38 | LambdaReadChat: 39 | Type: AWS::Lambda::Function 40 | Properties: 41 | FunctionName: !Sub "chat-read-${TeamName}" 42 | Description: "A read chat function" 43 | Handler: "index.handler" 44 | Role: 45 | Fn::GetAtt: [LambdaReadChatRole, "Arn"] 46 | Runtime: "nodejs6.10" 47 | MemorySize: "128" 48 | Timeout: "2" 49 | Code: 50 | "ZipFile": !Sub > 51 | var AWS = require('aws-sdk'); 52 | var dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'}); 53 | 54 | exports.handler = (event, context, callback) => { 55 | console.log("try to read chat"); 56 | 57 | }; 58 | 59 | Outputs: 60 | 61 | LambdaReadChatArn: 62 | Export: 63 | Name: !Sub "${AWS::StackName}-LambdaReadChatArn" 64 | Value: 65 | Fn::GetAtt: [LambdaReadChat, "Arn"] 66 | -------------------------------------------------------------------------------- /cloudformation/ec2/ci/pipeline.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | SCRIPT_DIR="$(cd "$(dirname "$0")" ; pwd -P)" 6 | 7 | if [ -z "${PROFILE}" ]; then 8 | echo "Please set environment variable PROFILE" 9 | exit 1 10 | fi 11 | 12 | if [ -z "${TEAM_NAME}" ]; then 13 | echo "Please set environment variable TEAM_NAME" 14 | exit 1 15 | fi 16 | 17 | REGION=${REGION:-"eu-central-1"} 18 | 19 | pushd "${SCRIPT_DIR}/.." > /dev/null 20 | 21 | bundle check || bundle install 22 | 23 | bundle exec autostacker24 validate --template cf-templates/vpc.yaml \ 24 | --profile "${PROFILE}" \ 25 | --region "${REGION}" 26 | 27 | # 1. Deploy vpc 28 | bundle exec autostacker24 update --template cf-templates/vpc.yaml \ 29 | --params properties/vpc.yaml \ 30 | --stack "vpc-${TEAM_NAME}" \ 31 | --region "${REGION}" \ 32 | --profile "${PROFILE}" 33 | 34 | # 2. Deploy debug security group 35 | #bundle exec autostacker24 validate --template cf-templates/vpc-debug-security-group.yaml \ 36 | # --profile "${PROFILE}" \ 37 | # --region "${REGION}" 38 | #bundle exec autostacker24 update --template cf-templates/vpc-debug-security-group.yaml \ 39 | # --stack "vpc-${TEAM_NAME}-debug-sg" \ 40 | # --param VPCStackName="vpc-${TEAM_NAME}" \ 41 | # --param TeamName="${TEAM_NAME}" \ 42 | # --region "${REGION}" \ 43 | # --profile "${PROFILE}" 44 | 45 | # 3. Deploy yocto 46 | #bundle exec autostacker24 validate --template cf-templates/vpc-yocto.yaml \ 47 | # --profile "${PROFILE}" \ 48 | # --region "${REGION}" 49 | #bundle exec autostacker24 update --template cf-templates/vpc-yocto.yaml \ 50 | # --params properties/yocto.yaml \ 51 | # --stack "vpc-${TEAM_NAME}-yocto" \ 52 | # --region "${REGION}" \ 53 | # --profile "${PROFILE}" 54 | 55 | # 4. Run integration tests if YOCTO_URL present 56 | if [ -n "${YOCTO_URL}" ]; then 57 | echo -e "\nStarting integration tests .." 58 | ./ci/integration-test.sh 59 | else 60 | echo -e "\nSet YOCTO_URL to run integration tests" 61 | fi 62 | 63 | popd > /dev/null 64 | -------------------------------------------------------------------------------- /cloudformation/fargate/ci/pipeline.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | SCRIPT_DIR="$(cd "$(dirname "$0")" ; pwd -P)" 6 | 7 | if [ -z "${PROFILE}" ]; then 8 | echo "Please set environment variable PROFILE" 9 | exit 1 10 | fi 11 | 12 | if [ -z "${TEAM_NAME}" ]; then 13 | echo "Please set environment variable TEAM_NAME" 14 | exit 1 15 | fi 16 | 17 | REGION=${REGION:-"eu-central-1"} 18 | 19 | pushd "${SCRIPT_DIR}/.." > /dev/null 20 | 21 | bundle check || bundle install 22 | 23 | bundle exec autostacker24 validate --template cf-templates/vpc.yaml \ 24 | --profile "${PROFILE}" \ 25 | --region "${REGION}" 26 | 27 | # 1. Deploy vpc 28 | bundle exec autostacker24 update --template cf-templates/vpc.yaml \ 29 | --params properties/vpc.yaml \ 30 | --stack "${TEAM_NAME}-vpc" \ 31 | --region "${REGION}" \ 32 | --profile "${PROFILE}" 33 | 34 | # 2. Deploy fargate resources 35 | bundle exec autostacker24 validate --template cf-templates/resources.yaml \ 36 | --profile "${PROFILE}" \ 37 | --region "${REGION}" 38 | bundle exec autostacker24 update --template cf-templates/resources.yaml \ 39 | --stack "${TEAM_NAME}-resources" \ 40 | --param VPCStackName="${TEAM_NAME}-vpc" \ 41 | --param TeamName="${TEAM_NAME}" \ 42 | --region "${REGION}" \ 43 | --profile "${PROFILE}" 44 | 45 | # 3. Deploy yocto 46 | bundle exec autostacker24 validate --template cf-templates/service.yaml \ 47 | --profile "${PROFILE}" \ 48 | --region "${REGION}" 49 | bundle exec autostacker24 update --template cf-templates/service.yaml \ 50 | --stack "${TEAM_NAME}-yocto" \ 51 | --param VPCStackName="${TEAM_NAME}-vpc" \ 52 | --param ResourcesStackName="${TEAM_NAME}-resources" \ 53 | --param TeamName="${TEAM_NAME}" \ 54 | --region "${REGION}" \ 55 | --profile "${PROFILE}" 56 | 57 | # 4. Run integration tests if YOCTO_URL present 58 | if [ -n "${YOCTO_URL}" ]; then 59 | echo -e "\nStarting integration tests .." 60 | ./ci/integration-test.sh 61 | else 62 | echo -e "\nSet YOCTO_URL to run integration tests" 63 | fi 64 | 65 | popd > /dev/null 66 | -------------------------------------------------------------------------------- /4cheaters/cloudformation/lambda/cf-templates/chat-read.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | 4 | Parameters: 5 | TeamName: 6 | Type: String 7 | 8 | Resources: 9 | 10 | LambdaReadChatRole: 11 | Type: AWS::IAM::Role 12 | Properties: 13 | Path: "/" 14 | AssumeRolePolicyDocument: 15 | Version: '2012-10-17' 16 | Statement: 17 | - Effect: "Allow" 18 | Principal: 19 | Service: 20 | - lambda.amazonaws.com 21 | Action: 22 | - sts:AssumeRole 23 | ManagedPolicyArns: 24 | - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" 25 | Policies: 26 | - PolicyName: "ApiGatewayLogsPolicy" 27 | PolicyDocument: 28 | Version: "2012-10-17" 29 | Statement: 30 | - Effect: "Allow" 31 | Action: 32 | - "dynamodb:BatchGetItem" 33 | - "dynamodb:GetItem" 34 | - "dynamodb:Scan" 35 | - "dynamodb:Query" 36 | Resource: "*" 37 | 38 | LambdaReadChat: 39 | Type: AWS::Lambda::Function 40 | Properties: 41 | FunctionName: !Sub "chat-read-${TeamName}" 42 | Description: "A read chat function" 43 | Handler: "index.handler" 44 | Role: 45 | Fn::GetAtt: [LambdaReadChatRole, "Arn"] 46 | Runtime: "nodejs6.10" 47 | MemorySize: "128" 48 | Timeout: "2" 49 | Code: 50 | "ZipFile": !Sub > 51 | var AWS = require('aws-sdk'); 52 | var dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'}); 53 | 54 | exports.handler = (event, context, callback) => { 55 | console.log("try to read chat"); 56 | var params = { 57 | TableName: "${TeamName}-chat", 58 | Limit: 10, 59 | }; 60 | 61 | dynamodb.scan(params, function(err, data) { 62 | callback(null, { 63 | input: event, 64 | err: err, 65 | output: data 66 | }); 67 | }); 68 | }; 69 | 70 | Outputs: 71 | 72 | LambdaReadChatArn: 73 | Export: 74 | Name: !Sub "${AWS::StackName}-LambdaReadChatArn" 75 | Value: 76 | Fn::GetAtt: [LambdaReadChat, "Arn"] 77 | -------------------------------------------------------------------------------- /4cheaters/cloudformation/lambda/ci/pipeline.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPT_DIR="$(cd "$(dirname "$0")" ; pwd -P)" 4 | 5 | if [ -z "${PROFILE}" ]; then 6 | echo "Please set environment variable PROFILE" 7 | exit 1 8 | fi 9 | 10 | if [ -z "${TEAM_NAME}" ]; then 11 | echo "Please set environment variable TEAM_NAME" 12 | exit 1 13 | fi 14 | 15 | REGION=${REGION:-"eu-central-1"} 16 | 17 | pushd "${SCRIPT_DIR}/.." > /dev/null 18 | 19 | bundle check || bundle install 20 | 21 | # 1. Deploy resources 22 | bundle exec autostacker24 validate --template cf-templates/chat-resources.yaml \ 23 | --profile "${PROFILE}" \ 24 | --region "${REGION}" 25 | 26 | bundle exec autostacker24 update --template cf-templates/chat-resources.yaml \ 27 | --stack "lambda-chat-${TEAM_NAME}-resources" \ 28 | --param TeamName="${TEAM_NAME}" \ 29 | --profile "${PROFILE}" \ 30 | --region "${REGION}" 31 | 32 | # 2. Deploy read lambda 33 | bundle exec autostacker24 validate --template cf-templates/chat-read.yaml \ 34 | --profile "${PROFILE}" \ 35 | --region "${REGION}" 36 | bundle exec autostacker24 update --template cf-templates/chat-read.yaml \ 37 | --stack "lambda-chat-${TEAM_NAME}-read" \ 38 | --param TeamName="${TEAM_NAME}" \ 39 | --profile "${PROFILE}" \ 40 | --region "${REGION}" 41 | 42 | # 3. Deploy write lambda 43 | bundle exec autostacker24 validate --template cf-templates/chat-write.yaml \ 44 | --profile "${PROFILE}" \ 45 | --region "${REGION}" 46 | bundle exec autostacker24 update --template cf-templates/chat-write.yaml \ 47 | --stack "lambda-chat-${TEAM_NAME}-write" \ 48 | --param TeamName="${TEAM_NAME}" \ 49 | --profile "${PROFILE}" \ 50 | --region "${REGION}" 51 | 52 | # 4. Deploy api 53 | bundle exec autostacker24 validate --template cf-templates/chat-api.yaml \ 54 | --profile "${PROFILE}" \ 55 | --region "${REGION}" 56 | bundle exec autostacker24 update --template cf-templates/chat-api.yaml \ 57 | --stack "lambda-chat-${TEAM_NAME}-api" \ 58 | --param TeamName="${TEAM_NAME}" \ 59 | --profile "${PROFILE}" \ 60 | --region "${REGION}" 61 | 62 | # 5. Run integration tests if API_GATEWAY_ID present 63 | if [ -n "${API_GATEWAY_ID}" ]; then 64 | echo -e "\nStarting integration tests .." 65 | ./ci/integration-test.sh 66 | else 67 | echo -e "\nSet API_GATEWAY_ID to run integration tests" 68 | fi 69 | 70 | popd > /dev/null 71 | -------------------------------------------------------------------------------- /cloudformation/lambda/ci/pipeline.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPT_DIR="$(cd "$(dirname "$0")" ; pwd -P)" 4 | 5 | if [ -z "${PROFILE}" ]; then 6 | echo "Please set environment variable PROFILE" 7 | exit 1 8 | fi 9 | 10 | if [ -z "${TEAM_NAME}" ]; then 11 | echo "Please set environment variable TEAM_NAME" 12 | exit 1 13 | fi 14 | 15 | REGION=${REGION:-"eu-central-1"} 16 | 17 | pushd "${SCRIPT_DIR}/.." > /dev/null 18 | 19 | bundle check || bundle install 20 | 21 | # 1. Deploy resources 22 | bundle exec autostacker24 validate --template cf-templates/chat-resources.yaml \ 23 | --profile "${PROFILE}" \ 24 | --region "${REGION}" 25 | 26 | bundle exec autostacker24 update --template cf-templates/chat-resources.yaml \ 27 | --stack "lambda-chat-${TEAM_NAME}-resources" \ 28 | --param TeamName="${TEAM_NAME}" \ 29 | --profile "${PROFILE}" \ 30 | --region "${REGION}" 31 | 32 | # 2. Deploy read lambda 33 | #bundle exec autostacker24 validate --template cf-templates/chat-read.yaml \ 34 | # --profile "${PROFILE}" \ 35 | # --region "${REGION}" 36 | #bundle exec autostacker24 update --template cf-templates/chat-read.yaml \ 37 | # --stack "lambda-chat-${TEAM_NAME}-read" \ 38 | # --param TeamName="${TEAM_NAME}" \ 39 | # --profile "${PROFILE}" \ 40 | # --region "${REGION}" 41 | 42 | # 3. Deploy write lambda 43 | #bundle exec autostacker24 validate --template cf-templates/chat-write.yaml \ 44 | # --profile "${PROFILE}" \ 45 | # --region "${REGION}" 46 | #bundle exec autostacker24 update --template cf-templates/chat-write.yaml \ 47 | # --stack "lambda-chat-${TEAM_NAME}-write" \ 48 | # --param TeamName="${TEAM_NAME}" \ 49 | # --profile "${PROFILE}" \ 50 | # --region "${REGION}" 51 | 52 | # 4. Deploy api 53 | #bundle exec autostacker24 validate --template cf-templates/chat-api.yaml \ 54 | # --profile "${PROFILE}" \ 55 | # --region "${REGION}" 56 | #bundle exec autostacker24 update --template cf-templates/chat-api.yaml \ 57 | # --stack "lambda-chat-${TEAM_NAME}-api" \ 58 | # --param TeamName="${TEAM_NAME}" \ 59 | # --profile "${PROFILE}" \ 60 | # --region "${REGION}" 61 | 62 | # 5. Run integration tests if API_GATEWAY_ID present 63 | if [ -n "${API_GATEWAY_ID}" ]; then 64 | echo -e "\nStarting integration tests .." 65 | ./ci/integration-test.sh 66 | else 67 | echo -e "\nSet API_GATEWAY_ID to run integration tests" 68 | fi 69 | 70 | popd > /dev/null 71 | -------------------------------------------------------------------------------- /4cheaters/cloudformation/lambda/cf-templates/chat-write.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | 4 | Parameters: 5 | TeamName: 6 | Type: String 7 | 8 | Resources: 9 | 10 | LambdaWriteChatRole: 11 | Type: AWS::IAM::Role 12 | Properties: 13 | Path: "/" 14 | AssumeRolePolicyDocument: 15 | Version: '2012-10-17' 16 | Statement: 17 | - Effect: "Allow" 18 | Principal: 19 | Service: 20 | - lambda.amazonaws.com 21 | Action: 22 | - sts:AssumeRole 23 | ManagedPolicyArns: 24 | - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" 25 | Policies: 26 | - PolicyName: "ApiGatewayLogsPolicy" 27 | PolicyDocument: 28 | Version: "2012-10-17" 29 | Statement: 30 | - Effect: "Allow" 31 | Action: 32 | - "dynamodb:PutItem" 33 | Resource: "*" 34 | 35 | LambdaWriteChat: 36 | Type: AWS::Lambda::Function 37 | Properties: 38 | Description: "A chat write function" 39 | FunctionName: !Sub "chat-write-${TeamName}" 40 | Handler: "index.handler" 41 | Role: 42 | Fn::GetAtt: [LambdaWriteChatRole, "Arn"] 43 | Runtime: "nodejs6.10" 44 | MemorySize: "128" 45 | Timeout: "2" 46 | Code: 47 | "ZipFile": !Sub > 48 | var AWS = require('aws-sdk'); 49 | var dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'}); 50 | 51 | exports.handler = (event, context, callback) => { 52 | console.log('Event:', JSON.stringify(event)); 53 | console.log("try to save message"); 54 | 55 | var timestamp = new Date().getTime().toString(); 56 | dynamodb.putItem({ 57 | "TableName": "${TeamName}-chat", 58 | "Item" : { 59 | "timestamp": {"N": timestamp }, 60 | "username": {"S": event.username }, 61 | "message": {"S": event.message} 62 | } 63 | }, function(err, data) { 64 | if (err) { 65 | console.log(JSON.stringify(err)); 66 | callback('putting item failed: ' + err); 67 | } 68 | else { 69 | console.log('success: ' + JSON.stringify(data)); 70 | } 71 | }); 72 | }; 73 | 74 | Outputs: 75 | 76 | LambdaWriteChatArn: 77 | Export: 78 | Name: !Sub "${AWS::StackName}-LambdaWriteChatArn" 79 | Value: 80 | Fn::GetAtt: [LambdaWriteChat, "Arn"] 81 | -------------------------------------------------------------------------------- /4cheaters/terraform/tf-files/yocto.tf: -------------------------------------------------------------------------------- 1 | resource "aws_security_group" "instance" { 2 | name = "Allow access to instance" 3 | vpc_id = "${aws_vpc.vpc.id}" 4 | 5 | ingress { 6 | from_port = 8080 7 | protocol = "tcp" 8 | to_port = 8080 9 | security_groups = ["${aws_security_group.elb.id}"] 10 | } 11 | 12 | egress { 13 | from_port = 0 14 | protocol = "-1" 15 | to_port = 0 16 | cidr_blocks = ["0.0.0.0/0"] 17 | } 18 | 19 | tags { 20 | Name = "${var.team_name}-yocto-instance-sg" 21 | } 22 | } 23 | 24 | resource "aws_security_group" "elb" { 25 | name = "Allow public access to elb" 26 | vpc_id = "${aws_vpc.vpc.id}" 27 | 28 | ingress { 29 | from_port = 80 30 | protocol = "tcp" 31 | to_port = 80 32 | cidr_blocks = [ 33 | "0.0.0.0/0"] 34 | } 35 | 36 | egress { 37 | from_port = 0 38 | protocol = "-1" 39 | to_port = 0 40 | cidr_blocks = ["0.0.0.0/0"] 41 | } 42 | 43 | tags { 44 | Name = "${var.team_name}-yocto-elb-sg" 45 | } 46 | } 47 | 48 | data "template_file" "userdata" { 49 | template = "${file("${path.module}/userdata.tpl")}" 50 | } 51 | 52 | resource "aws_launch_configuration" "yoctolaunch" { 53 | name_prefix = "${var.team_name}-" 54 | image_id = "${var.ami_id}" 55 | instance_type = "${var.instance_type}" 56 | key_name = "${var.sshkeyname}" 57 | user_data = "${data.template_file.userdata.rendered}" 58 | security_groups = ["${aws_security_group.instance.id}"] 59 | associate_public_ip_address = true 60 | lifecycle { create_before_destroy = true } 61 | } 62 | 63 | resource "aws_autoscaling_group" "yoctoautoscaling" { 64 | name_prefix = "${var.team_name}-" 65 | launch_configuration = "${aws_launch_configuration.yoctolaunch.id}" 66 | max_size = 2 67 | min_size = 1 68 | desired_capacity = 1 69 | vpc_zone_identifier = ["${aws_subnet.publicsubnets.*.id}"] 70 | load_balancers = ["${aws_elb.yocto.id}"] 71 | health_check_type = "ELB" 72 | health_check_grace_period = 120 73 | wait_for_capacity_timeout = "3m" 74 | 75 | lifecycle {create_before_destroy = true} 76 | 77 | tags = [ 78 | { 79 | key = "Name" 80 | value = "${var.team_name}-yocto" 81 | propagate_at_launch = true 82 | } 83 | ] 84 | } 85 | 86 | resource "aws_elb" "yocto" { 87 | name = "${var.team_name}-yocto-elb" 88 | subnets = ["${aws_subnet.publicsubnets.*.id}"] 89 | security_groups = ["${aws_security_group.elb.id}"] 90 | listener { 91 | instance_port = 8080 92 | instance_protocol = "http" 93 | lb_port = 80 94 | lb_protocol = "http" 95 | } 96 | health_check { 97 | healthy_threshold = 2 98 | interval = 5 99 | target = "HTTP:8080/status" 100 | timeout = 2 101 | unhealthy_threshold = 2 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /cloudformation/fargate/cf-templates/service.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | 3 | Parameters: 4 | VPCStackName: 5 | Type: String 6 | ResourcesStackName: 7 | Type: String 8 | TeamName: 9 | Type: String 10 | ServiceName: 11 | Type: String 12 | Default: 'yocto' 13 | Description: A name for the service 14 | ImageUrl: 15 | Type: String 16 | Default: 'felixb/yocto-httpd' 17 | Description: The url of a docker image that contains the application process that 18 | will handle the traffic for this service 19 | ContainerPort: 20 | Type: Number 21 | Default: 8080 22 | Description: What port number the application inside the docker container is binding to 23 | ContainerCpu: 24 | Type: Number 25 | Default: 256 26 | Description: How much CPU to give the container. 1024 is 1 CPU. Max is 10240. 27 | ContainerMemory: 28 | Type: Number 29 | Default: 1024 30 | Description: How much memory in megabytes to give the container 31 | DesiredCount: 32 | Type: Number 33 | Default: 1 34 | Description: How many copies of the service task to run 35 | 36 | Resources: 37 | CloudwatchLogsGroup: 38 | Type: AWS::Logs::LogGroup 39 | Properties: 40 | LogGroupName: 'yocto' 41 | RetentionInDays: 3 42 | 43 | # The task definition. This is a simple metadata description of what 44 | # container to run, and what resource requirements it has. 45 | # Counterpart in ec2 is the launch configuration 46 | TaskDefinition: 47 | Type: AWS::ECS::TaskDefinition 48 | Properties: 49 | Family: !Ref 'ServiceName' 50 | Cpu: !Ref 'ContainerCpu' 51 | Memory: !Ref 'ContainerMemory' 52 | NetworkMode: awsvpc 53 | RequiresCompatibilities: 54 | - FARGATE 55 | ExecutionRoleArn: !ImportValue {"Fn::Sub": "${ResourcesStackName}:ECSTaskExecutionRole"} 56 | ContainerDefinitions: 57 | - Name: !Ref 'ServiceName' 58 | Cpu: !Ref 'ContainerCpu' 59 | Memory: !Ref 'ContainerMemory' 60 | Image: !Ref 'ImageUrl' 61 | PortMappings: 62 | - 63 | ContainerPort: !Ref 'ContainerPort' 64 | HostPort: !Ref 'ContainerPort' 65 | LogConfiguration: 66 | LogDriver: awslogs 67 | Options: 68 | awslogs-group: !Ref 'CloudwatchLogsGroup' 69 | awslogs-region: 'eu-central-1' 70 | awslogs-stream-prefix: 'yocto' 71 | 72 | 73 | # The service. The service is a resource which allows you to run multiple 74 | # copies of a type of task, and gather up their logs and metrics, as well 75 | # as monitor the number of running tasks and replace any that have crashed 76 | Service: 77 | Type: AWS::ECS::Service 78 | Properties: 79 | ServiceName: !Ref 'ServiceName' 80 | Cluster: !ImportValue {"Fn::Sub": "${ResourcesStackName}:ClusterName"} 81 | LaunchType: FARGATE 82 | DeploymentConfiguration: 83 | MaximumPercent: 200 84 | MinimumHealthyPercent: 75 85 | DesiredCount: !Ref 'DesiredCount' 86 | NetworkConfiguration: 87 | AwsvpcConfiguration: 88 | AssignPublicIp: ENABLED 89 | SecurityGroups: 90 | - !ImportValue {"Fn::Sub": "${ResourcesStackName}:SecurityGroup"} 91 | Subnets: 92 | - !ImportValue {"Fn::Sub": "${VPCStackName}-subnet-1-public-id"} 93 | - !ImportValue {"Fn::Sub": "${VPCStackName}-subnet-2-public-id"} 94 | TaskDefinition: !Ref 'TaskDefinition' 95 | -------------------------------------------------------------------------------- /cloudformation/ec2/cf-templates/vpc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: "2010-09-09" 3 | 4 | Parameters: 5 | TeamName: 6 | Type: String 7 | DnsRootDomain: 8 | Type: String 9 | VpcCidr: 10 | Type: String 11 | VpcSubnet1Cidr: 12 | Type: String 13 | VpcSubnet2Cidr: 14 | Type: String 15 | VpcSubnet3Cidr: 16 | Type: String 17 | 18 | Resources: 19 | VPC: 20 | Type: AWS::EC2::VPC 21 | Properties: 22 | CidrBlock: !Ref VpcCidr 23 | EnableDnsSupport: true 24 | EnableDnsHostnames: false 25 | InstanceTenancy: default 26 | Tags: 27 | - Key: Name 28 | Value: !Sub "${TeamName}" 29 | 30 | InternetGateway: 31 | Type: AWS::EC2::InternetGateway 32 | 33 | AttachGateway: 34 | Type: AWS::EC2::VPCGatewayAttachment 35 | Properties: 36 | VpcId: !Ref VPC 37 | InternetGatewayId: !Ref InternetGateway 38 | 39 | RouteTable: 40 | Type: AWS::EC2::RouteTable 41 | Properties: 42 | VpcId: !Ref VPC 43 | Tags: 44 | - Key: Name 45 | Value: !Sub "${TeamName}-route-table-public" 46 | 47 | RoutePublic: 48 | Type: AWS::EC2::Route 49 | Properties: 50 | RouteTableId: !Ref RouteTable 51 | DestinationCidrBlock: 0.0.0.0/0 52 | GatewayId: !Ref InternetGateway 53 | 54 | Subnet1Public: 55 | Type: AWS::EC2::Subnet 56 | Properties: 57 | VpcId: !Ref VPC 58 | MapPublicIpOnLaunch: true 59 | CidrBlock: !Ref VpcSubnet1Cidr 60 | AvailabilityZone: "eu-central-1a" 61 | Tags: 62 | - Key: Name 63 | Value: !Sub "${TeamName}-public-1" 64 | RouteTableAssociation1Public: 65 | Type: AWS::EC2::SubnetRouteTableAssociation 66 | Properties: 67 | SubnetId: !Ref Subnet1Public 68 | RouteTableId: !Ref RouteTable 69 | 70 | Subnet2Public: 71 | Type: AWS::EC2::Subnet 72 | Properties: 73 | VpcId: !Ref VPC 74 | MapPublicIpOnLaunch: true 75 | CidrBlock: !Ref VpcSubnet2Cidr 76 | AvailabilityZone: "eu-central-1b" 77 | Tags: 78 | - Key: Name 79 | Value: !Sub "${TeamName}-public-2" 80 | RouteTableAssociation2Public: 81 | Type: AWS::EC2::SubnetRouteTableAssociation 82 | Properties: 83 | SubnetId: !Ref Subnet2Public 84 | RouteTableId: !Ref RouteTable 85 | 86 | Subnet3Public: 87 | Type: AWS::EC2::Subnet 88 | Properties: 89 | VpcId: !Ref VPC 90 | MapPublicIpOnLaunch: true 91 | CidrBlock: !Ref VpcSubnet3Cidr 92 | AvailabilityZone: "eu-central-1c" 93 | Tags: 94 | - Key: Name 95 | Value: !Sub "${TeamName}-public-3" 96 | RouteTableAssociation3Public: 97 | Type: AWS::EC2::SubnetRouteTableAssociation 98 | Properties: 99 | SubnetId: !Ref Subnet3Public 100 | RouteTableId: !Ref RouteTable 101 | 102 | Outputs: 103 | VPCId: 104 | Export: 105 | Name: !Sub "${AWS::StackName}-vpc-id" 106 | Value: !Ref VPC 107 | VPCCidr: 108 | Export: 109 | Name: !Sub "${AWS::StackName}-vpc-cidr" 110 | Value: !Ref VpcCidr 111 | Subnet1PublicId: 112 | Export: 113 | Name: !Sub "${AWS::StackName}-subnet-1-public-id" 114 | Value: !Ref Subnet1Public 115 | Subnet2PublicId: 116 | Export: 117 | Name: !Sub "${AWS::StackName}-subnet-2-public-id" 118 | Value: !Ref Subnet2Public 119 | Subnet3PublicId: 120 | Export: 121 | Name: !Sub "${AWS::StackName}-subnet-3-public-id" 122 | Value: !Ref Subnet3Public 123 | -------------------------------------------------------------------------------- /cloudformation/fargate/cf-templates/vpc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: "2010-09-09" 3 | 4 | Parameters: 5 | TeamName: 6 | Type: String 7 | DnsRootDomain: 8 | Type: String 9 | VpcCidr: 10 | Type: String 11 | VpcSubnet1Cidr: 12 | Type: String 13 | VpcSubnet2Cidr: 14 | Type: String 15 | VpcSubnet3Cidr: 16 | Type: String 17 | 18 | Resources: 19 | VPC: 20 | Type: AWS::EC2::VPC 21 | Properties: 22 | CidrBlock: !Ref VpcCidr 23 | EnableDnsSupport: true 24 | EnableDnsHostnames: false 25 | InstanceTenancy: default 26 | Tags: 27 | - Key: Name 28 | Value: !Sub "${TeamName}" 29 | 30 | InternetGateway: 31 | Type: AWS::EC2::InternetGateway 32 | 33 | AttachGateway: 34 | Type: AWS::EC2::VPCGatewayAttachment 35 | Properties: 36 | VpcId: !Ref VPC 37 | InternetGatewayId: !Ref InternetGateway 38 | 39 | RouteTable: 40 | Type: AWS::EC2::RouteTable 41 | Properties: 42 | VpcId: !Ref VPC 43 | Tags: 44 | - Key: Name 45 | Value: !Sub "${TeamName}-route-table-public" 46 | 47 | RoutePublic: 48 | Type: AWS::EC2::Route 49 | Properties: 50 | RouteTableId: !Ref RouteTable 51 | DestinationCidrBlock: 0.0.0.0/0 52 | GatewayId: !Ref InternetGateway 53 | 54 | Subnet1Public: 55 | Type: AWS::EC2::Subnet 56 | Properties: 57 | VpcId: !Ref VPC 58 | MapPublicIpOnLaunch: true 59 | CidrBlock: !Ref VpcSubnet1Cidr 60 | AvailabilityZone: "eu-central-1a" 61 | Tags: 62 | - Key: Name 63 | Value: !Sub "${TeamName}-public-1" 64 | RouteTableAssociation1Public: 65 | Type: AWS::EC2::SubnetRouteTableAssociation 66 | Properties: 67 | SubnetId: !Ref Subnet1Public 68 | RouteTableId: !Ref RouteTable 69 | 70 | Subnet2Public: 71 | Type: AWS::EC2::Subnet 72 | Properties: 73 | VpcId: !Ref VPC 74 | MapPublicIpOnLaunch: true 75 | CidrBlock: !Ref VpcSubnet2Cidr 76 | AvailabilityZone: "eu-central-1b" 77 | Tags: 78 | - Key: Name 79 | Value: !Sub "${TeamName}-public-2" 80 | RouteTableAssociation2Public: 81 | Type: AWS::EC2::SubnetRouteTableAssociation 82 | Properties: 83 | SubnetId: !Ref Subnet2Public 84 | RouteTableId: !Ref RouteTable 85 | 86 | Subnet3Public: 87 | Type: AWS::EC2::Subnet 88 | Properties: 89 | VpcId: !Ref VPC 90 | MapPublicIpOnLaunch: true 91 | CidrBlock: !Ref VpcSubnet3Cidr 92 | AvailabilityZone: "eu-central-1c" 93 | Tags: 94 | - Key: Name 95 | Value: !Sub "${TeamName}-public-3" 96 | RouteTableAssociation3Public: 97 | Type: AWS::EC2::SubnetRouteTableAssociation 98 | Properties: 99 | SubnetId: !Ref Subnet3Public 100 | RouteTableId: !Ref RouteTable 101 | 102 | Outputs: 103 | VPCId: 104 | Export: 105 | Name: !Sub "${AWS::StackName}-vpc-id" 106 | Value: !Ref VPC 107 | VPCCidr: 108 | Export: 109 | Name: !Sub "${AWS::StackName}-vpc-cidr" 110 | Value: !Ref VpcCidr 111 | Subnet1PublicId: 112 | Export: 113 | Name: !Sub "${AWS::StackName}-subnet-1-public-id" 114 | Value: !Ref Subnet1Public 115 | Subnet2PublicId: 116 | Export: 117 | Name: !Sub "${AWS::StackName}-subnet-2-public-id" 118 | Value: !Ref Subnet2Public 119 | Subnet3PublicId: 120 | Export: 121 | Name: !Sub "${AWS::StackName}-subnet-3-public-id" 122 | Value: !Ref Subnet3Public 123 | -------------------------------------------------------------------------------- /cloudformation/lambda/cf-templates/chat-api.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | 4 | Parameters: 5 | TeamName: 6 | Type: String 7 | 8 | Resources: 9 | 10 | ChatApi: 11 | Type: AWS::ApiGateway::RestApi 12 | Properties: 13 | Name: !Sub "chat-api-${TeamName}" 14 | Description: "API used for chatting" 15 | FailOnWarnings: "true" 16 | 17 | ChatApiResource: 18 | Type: AWS::ApiGateway::Resource 19 | Properties: 20 | RestApiId: !Ref ChatApi 21 | ParentId: 22 | Fn::GetAtt: [ChatApi, "RootResourceId"] 23 | PathPart: "chat" 24 | 25 | ###### Read chat ###### 26 | 27 | LambdaReadChatPermissionForApiGateway: 28 | Type: "AWS::Lambda::Permission" 29 | Properties: 30 | Action: "lambda:invokeFunction" 31 | FunctionName: !ImportValue {"Fn::Sub": "lambda-chat-${TeamName}-read-LambdaReadChatArn"} 32 | Principal: "apigateway.amazonaws.com" 33 | SourceArn: 34 | Fn::Join: ["", ["arn:aws:execute-api:", {"Ref": "AWS::Region"}, ":", {"Ref": "AWS::AccountId"}, ":", {"Ref": "ChatApi"}, "/*"]] 35 | 36 | ReadChatRequest: 37 | Type: AWS::ApiGateway::Method 38 | Properties: 39 | AuthorizationType: "NONE" 40 | HttpMethod: "GET" 41 | Integration: 42 | Type: "AWS" 43 | IntegrationHttpMethod: "POST" 44 | Uri: 45 | Fn::Join: ["", ["arn:aws:apigateway:", {"Ref": "AWS::Region"}, ":lambda:path/2015-03-31/functions/", !ImportValue {"Fn::Sub": "lambda-chat-${TeamName}-read-LambdaReadChatArn"}, "/invocations"]] 46 | IntegrationResponses: 47 | - StatusCode: 200 48 | ResourceId: !Ref ChatApiResource 49 | RestApiId: !Ref ChatApi 50 | MethodResponses: 51 | - StatusCode: 200 52 | 53 | ###### Write chat ###### 54 | 55 | 56 | 57 | ###### Api versions ###### 58 | 59 | ApiDeployment: 60 | Type: AWS::ApiGateway::Deployment 61 | DependsOn: [ ReadChatRequest ] 62 | Properties: 63 | RestApiId: !Ref ChatApi 64 | StageName: "TEST" 65 | 66 | ChatApiStage: 67 | DependsOn: [ChatApi] 68 | Type: AWS::ApiGateway::Stage 69 | Properties: 70 | DeploymentId: !Ref ApiDeployment 71 | MethodSettings: 72 | - DataTraceEnabled: true 73 | HttpMethod: "*" 74 | LoggingLevel: "INFO" 75 | ResourcePath: "/*" 76 | RestApiId: !Ref ChatApi 77 | StageName: "LATEST" 78 | 79 | ###### CloudWatch policy ###### 80 | 81 | ApiGatewayCloudWatchLogsRole: 82 | Type: "AWS::IAM::Role" 83 | Properties: 84 | AssumeRolePolicyDocument: 85 | Version: "2012-10-17" 86 | Statement: 87 | - Effect: "Allow" 88 | Principal: 89 | Service: 90 | - "apigateway.amazonaws.com" 91 | Action: 92 | - "sts:AssumeRole" 93 | Path: "/" 94 | Policies: 95 | - PolicyName: "ApiGatewayLogsPolicy" 96 | PolicyDocument: 97 | Version: "2012-10-17" 98 | Statement: 99 | - 100 | Effect: "Allow" 101 | Action: 102 | - "logs:CreateLogGroup" 103 | - "logs:CreateLogStream" 104 | - "logs:DescribeLogGroups" 105 | - "logs:DescribeLogStreams" 106 | - "logs:PutLogEvents" 107 | - "logs:GetLogEvents" 108 | - "logs:FilterLogEvents" 109 | Resource: "*" 110 | 111 | ApiGatewayAccount: 112 | Type: AWS::ApiGateway::Account 113 | Properties: 114 | CloudWatchRoleArn: 115 | Fn::GetAtt: ["ApiGatewayCloudWatchLogsRole", "Arn"] 116 | -------------------------------------------------------------------------------- /igor.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # This is igor. 4 | 5 | # Original project: https://github.com/felixb/igor 6 | 7 | # Install / update: 8 | # sudo curl https://raw.githubusercontent.com/felixb/igor/master/igor.sh -o /usr/local/bin/igor 9 | # sudo chmod +x /usr/local/bin/igor 10 | 11 | set -e 12 | 13 | # set up default values 14 | IGOR_DOCKER_IMAGE=busybox # select docker image 15 | IGOR_DOCKER_COMMAND=sh # run this command inside the docker conainer 16 | IGOR_DOCKER_PULL=0 # force pulling the image before starting the container (0/1) 17 | IGOR_DOCKER_RM=1 # remove container on exit (0/1) 18 | IGOR_DOCKER_TTY=1 # open an interactive tty (0/1) 19 | IGOR_DOCKER_USER=$(id -u) # run commands inside the container with this user 20 | IGOR_DOCKER_GROUP=$(id -g) # run commands inside the container with this group 21 | IGOR_DOCKER_ARGS='' # default arguments to docker run 22 | IGOR_PORTS='' # space separated list of ports to expose 23 | IGOR_MOUNT_PASSWD=0 # mount /etc/passwd inside the container (0/1) 24 | IGOR_MOUNT_GROUP=0 # mount /etc/group inside the container (0/1) 25 | IGOR_MOUNTS_RO='' # space separated list of volumes to mount read only 26 | IGOR_MOUNTS_RW='' # space separated list of volumes to mount read write 27 | IGOR_WORKDIR=${PWD} # use this workdir inside the container 28 | IGOR_WORKDIR_MODE=rw # mount the workdir with this mode (ro/rw) 29 | IGOR_ENV='' # space separated list of environment variables set inside the container 30 | 31 | igor_config=.igor.sh 32 | 33 | function usage() { 34 | echo "$0 [-v] [-c path-to-igor-config] [--help]" 35 | echo '' 36 | echo 'Opens a shell in your favorite docker container mounting your current workspace into the container' 37 | echo '' 38 | echo 'configuration files:' 39 | echo '' 40 | echo '~/.igor.sh' 41 | echo './.igor.sh or file specified with -c option' 42 | echo '' 43 | echo 'default config:' 44 | echo '' 45 | grep '^IGOR_' $0 46 | echo '' 47 | exit 1 48 | } 49 | 50 | # ugly command line parsing 51 | if [ "${1}" == '-v' ]; then 52 | shift 53 | set -x 54 | fi 55 | 56 | if [ "${1}" == '-c' ]; then 57 | if [ -z "${2}" ] || ! [ -e "${2}" ]; then 58 | usage 59 | fi 60 | igor_config="${2}" 61 | shift 62 | shift 63 | fi 64 | 65 | if [ "${1}" == '--help' ]; then 66 | usage 67 | fi 68 | 69 | # load config from home 70 | if [ -e "${HOME}/.igor.sh" ]; then 71 | . "${HOME}/.igor.sh" 72 | fi 73 | 74 | # load config from current working dir 75 | if [ -e "${igor_config}" ]; then 76 | . "${igor_config}" 77 | fi 78 | 79 | # assamble command line 80 | if [ ${IGOR_DOCKER_PULL} -gt 0 ]; then 81 | docker pull "${IGOR_DOCKER_IMAGE}" 82 | fi 83 | 84 | args='' 85 | if [ ${IGOR_DOCKER_RM} -gt 0 ]; then 86 | args="${args} --rm" 87 | fi 88 | if [ ${IGOR_DOCKER_TTY} -gt 0 ]; then 89 | args="${args} -ti" 90 | fi 91 | for p in ${IGOR_PORTS}; do 92 | args="${args} -p ${p}:${p}" 93 | done 94 | if [ ${IGOR_MOUNT_PASSWD} -gt 0 ]; then 95 | args="${args} -v /etc/passwd:/etc/passwd:ro" 96 | fi 97 | if [ ${IGOR_MOUNT_GROUP} -gt 0 ]; then 98 | args="${args} -v /etc/group:/etc/group:ro" 99 | fi 100 | for v in ${IGOR_MOUNTS_RO}; do 101 | args="${args} -v ${v}:${v}:ro" 102 | done 103 | for v in ${IGOR_MOUNTS_RW}; do 104 | args="${args} -v ${v}:${v}:rw" 105 | done 106 | for e in ${IGOR_ENV}; do 107 | args="${args} -e ${e}=${!e}" 108 | done 109 | 110 | # execute! 111 | exec docker run \ 112 | ${args} \ 113 | -u "${IGOR_DOCKER_USER}:${IGOR_DOCKER_GROUP}" \ 114 | -v "${PWD}:${IGOR_WORKDIR}:rw" \ 115 | -w "${IGOR_WORKDIR}" \ 116 | ${IGOR_DOCKER_ARGS} \ 117 | "${IGOR_DOCKER_IMAGE}" \ 118 | ${IGOR_DOCKER_COMMAND} -------------------------------------------------------------------------------- /4cheaters/cloudformation/ec2/cf-templates/vpc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: "2010-09-09" 3 | 4 | Parameters: 5 | TeamName: 6 | Type: String 7 | DnsRootDomain: 8 | Type: String 9 | VpcCidr: 10 | Type: String 11 | VpcSubnet1Cidr: 12 | Type: String 13 | VpcSubnet2Cidr: 14 | Type: String 15 | VpcSubnet3Cidr: 16 | Type: String 17 | 18 | Resources: 19 | VPC: 20 | Type: AWS::EC2::VPC 21 | Properties: 22 | CidrBlock: !Ref VpcCidr 23 | EnableDnsSupport: true 24 | EnableDnsHostnames: false 25 | InstanceTenancy: default 26 | Tags: 27 | - Key: Name 28 | Value: !Sub "${TeamName}" 29 | 30 | InternetGateway: 31 | Type: AWS::EC2::InternetGateway 32 | 33 | AttachGateway: 34 | Type: AWS::EC2::VPCGatewayAttachment 35 | Properties: 36 | VpcId: !Ref VPC 37 | InternetGatewayId: !Ref InternetGateway 38 | 39 | # dns zone of VPC -> delegation has to be configured in the root dns zone 40 | Route53HostedZone: 41 | Type: AWS::Route53::HostedZone 42 | Properties: 43 | Name: !Sub "${TeamName}.${DnsRootDomain}" 44 | 45 | RouteTable: 46 | Type: AWS::EC2::RouteTable 47 | Properties: 48 | VpcId: !Ref VPC 49 | Tags: 50 | - Key: Name 51 | Value: !Sub "${TeamName}-route-table-public" 52 | 53 | RoutePublic: 54 | Type: AWS::EC2::Route 55 | Properties: 56 | RouteTableId: !Ref RouteTable 57 | DestinationCidrBlock: 0.0.0.0/0 58 | GatewayId: !Ref InternetGateway 59 | 60 | Subnet1Public: 61 | Type: AWS::EC2::Subnet 62 | Properties: 63 | VpcId: !Ref VPC 64 | MapPublicIpOnLaunch: true 65 | CidrBlock: !Ref VpcSubnet1Cidr 66 | AvailabilityZone: !Select [ 0, { "Fn::GetAZs": { Ref: "AWS::Region" } } ] 67 | Tags: 68 | - Key: Name 69 | Value: !Sub "${TeamName}-public-1" 70 | RouteTableAssociation1Public: 71 | Type: AWS::EC2::SubnetRouteTableAssociation 72 | Properties: 73 | SubnetId: !Ref Subnet1Public 74 | RouteTableId: !Ref RouteTable 75 | 76 | Subnet2Public: 77 | Type: AWS::EC2::Subnet 78 | Properties: 79 | VpcId: !Ref VPC 80 | MapPublicIpOnLaunch: true 81 | CidrBlock: !Ref VpcSubnet2Cidr 82 | AvailabilityZone: !Select [ 1, { "Fn::GetAZs": { Ref: "AWS::Region" } } ] 83 | Tags: 84 | - Key: Name 85 | Value: !Sub "${TeamName}-public-2" 86 | RouteTableAssociation2Public: 87 | Type: AWS::EC2::SubnetRouteTableAssociation 88 | Properties: 89 | SubnetId: !Ref Subnet2Public 90 | RouteTableId: !Ref RouteTable 91 | 92 | Subnet3Public: 93 | Type: AWS::EC2::Subnet 94 | Properties: 95 | VpcId: !Ref VPC 96 | MapPublicIpOnLaunch: true 97 | CidrBlock: !Ref VpcSubnet3Cidr 98 | AvailabilityZone: !Select [ 2, { "Fn::GetAZs": { Ref: "AWS::Region" } } ] 99 | Tags: 100 | - Key: Name 101 | Value: !Sub "${TeamName}-public-3" 102 | RouteTableAssociation3Public: 103 | Type: AWS::EC2::SubnetRouteTableAssociation 104 | Properties: 105 | SubnetId: !Ref Subnet3Public 106 | RouteTableId: !Ref RouteTable 107 | 108 | Outputs: 109 | VPCId: 110 | Export: 111 | Name: !Sub "${AWS::StackName}-vpc-id" 112 | Value: !Ref VPC 113 | VPCCidr: 114 | Export: 115 | Name: !Sub "${AWS::StackName}-vpc-cidr" 116 | Value: !Ref VpcCidr 117 | HostedZoneId: 118 | Export: 119 | Name: !Sub "${AWS::StackName}-hosted-zone-id" 120 | Value: !Ref Route53HostedZone 121 | HostedZoneName: 122 | Export: 123 | Name: !Sub "${AWS::StackName}-hosted-zone-name" 124 | Value: !Sub "${TeamName}.${DnsRootDomain}" 125 | Subnet1PublicId: 126 | Export: 127 | Name: !Sub "${AWS::StackName}-subnet-1-public-id" 128 | Value: !Ref Subnet1Public 129 | Subnet2PublicId: 130 | Export: 131 | Name: !Sub "${AWS::StackName}-subnet-2-public-id" 132 | Value: !Ref Subnet2Public 133 | Subnet3PublicId: 134 | Export: 135 | Name: !Sub "${AWS::StackName}-subnet-3-public-id" 136 | Value: !Ref Subnet3Public 137 | -------------------------------------------------------------------------------- /cloudformation/fargate/cf-templates/resources.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | 3 | Parameters: 4 | VPCStackName: 5 | Type: String 6 | TeamName: 7 | Type: String 8 | 9 | Resources: 10 | 11 | ECSCluster: 12 | Type: AWS::ECS::Cluster 13 | 14 | SecurityGroup: 15 | Type: AWS::EC2::SecurityGroup 16 | Properties: 17 | GroupDescription: "Allow access via http" 18 | VpcId: !ImportValue {"Fn::Sub": "${VPCStackName}-vpc-id"} 19 | SecurityGroupIngress: 20 | - IpProtocol: "tcp" 21 | FromPort: "8080" 22 | ToPort: "8080" 23 | CidrIp: "0.0.0.0/0" 24 | Tags: 25 | - Key: Name 26 | Value: !Sub "${TeamName}-yocto" 27 | 28 | # This is an IAM role which authorizes ECS to manage resources on your 29 | # account on your behalf, such as updating your load balancer with the 30 | # details of where your containers are, so that traffic can reach your 31 | # containers. 32 | ECSRole: 33 | Type: AWS::IAM::Role 34 | Properties: 35 | RoleName: 'fargate-ecs-role' 36 | AssumeRolePolicyDocument: 37 | Statement: 38 | - Effect: Allow 39 | Principal: 40 | Service: [ecs.amazonaws.com] 41 | Action: ['sts:AssumeRole'] 42 | Path: / 43 | Policies: 44 | - PolicyName: ecs-service-policy 45 | PolicyDocument: 46 | Statement: 47 | - Effect: Allow 48 | Action: 49 | # Rules which allow ECS to attach network interfaces to instances 50 | # on your behalf in order for awsvpc networking mode to work right 51 | - 'ec2:AttachNetworkInterface' 52 | - 'ec2:CreateNetworkInterface' 53 | - 'ec2:CreateNetworkInterfacePermission' 54 | - 'ec2:DeleteNetworkInterface' 55 | - 'ec2:DeleteNetworkInterfacePermission' 56 | - 'ec2:Describe*' 57 | - 'ec2:DetachNetworkInterface' 58 | Resource: '*' 59 | 60 | # This is a role which is used by the ECS tasks themselves. 61 | ECSTaskExecutionRole: 62 | Type: AWS::IAM::Role 63 | Properties: 64 | RoleName: 'fargate-task-role' 65 | AssumeRolePolicyDocument: 66 | Statement: 67 | - Effect: Allow 68 | Principal: 69 | Service: [ecs-tasks.amazonaws.com] 70 | Action: ['sts:AssumeRole'] 71 | Path: / 72 | Policies: 73 | - PolicyName: ecs-task-execution-policy 74 | PolicyDocument: 75 | Statement: 76 | - Effect: Allow 77 | Action: 78 | # Allow the ECS Tasks to download images from ECR 79 | - 'ecr:GetAuthorizationToken' 80 | - 'ecr:BatchCheckLayerAvailability' 81 | - 'ecr:GetDownloadUrlForLayer' 82 | - 'ecr:BatchGetImage' 83 | # Allow task to write metrics 84 | - 'cloudwatch:PutMetricData' 85 | - 'cloudwatch:GetMetricStatistics' 86 | - 'cloudwatch:ListMetrics' 87 | # Allow task to write logs 88 | - 'logs:CreateLogGroup' 89 | - 'logs:CreateLogStream' 90 | - 'logs:PutLogEvents' 91 | Resource: '*' 92 | 93 | Outputs: 94 | ClusterName: 95 | Description: The name of the ECS cluster 96 | Value: !Ref 'ECSCluster' 97 | Export: 98 | Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ClusterName' ] ] 99 | ECSTaskExecutionRole: 100 | Description: The ARN of the ECS role 101 | Value: !GetAtt 'ECSTaskExecutionRole.Arn' 102 | Export: 103 | Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ECSTaskExecutionRole' ] ] 104 | ApplicationAutoScalingRole: 105 | Description: The ARN of the ECS Autoscaling role 106 | Value: !GetAtt 'ApplicationAutoScalingRole.Arn' 107 | Export: 108 | Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ApplicationAutoScalingRole' ] ] 109 | SecurityGroup: 110 | Description: A security group used to allow Fargate containers to receive traffic 111 | Value: !Ref 'SecurityGroup' 112 | Export: 113 | Name: !Join [ ':', [ !Ref 'AWS::StackName', 'SecurityGroup' ] ] -------------------------------------------------------------------------------- /cloudformation/ec2/cf-templates/vpc-yocto.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: "2010-09-09" 3 | 4 | Parameters: 5 | VPCStackName: 6 | Type: String 7 | TeamName: 8 | Type: String 9 | ImageId: 10 | Type: String 11 | KeyName: 12 | Type: String 13 | 14 | Resources: 15 | 16 | ###### EC2 instance ###### 17 | 18 | SecurityGroup: 19 | Type: AWS::EC2::SecurityGroup 20 | Properties: 21 | GroupDescription: "Allow access via http" 22 | VpcId: !ImportValue {"Fn::Sub": "${VPCStackName}-vpc-id"} 23 | SecurityGroupIngress: 24 | - IpProtocol: "tcp" 25 | FromPort: "8080" 26 | ToPort: "8080" 27 | CidrIp: "0.0.0.0/0" 28 | Tags: 29 | - Key: Name 30 | Value: !Sub "${TeamName}-yocto" 31 | 32 | Role: 33 | Type: AWS::IAM::Role 34 | Properties: 35 | AssumeRolePolicyDocument: 36 | Version: "2012-10-17" 37 | Statement: 38 | - Effect: Allow 39 | Principal: 40 | Service: 41 | - ec2.amazonaws.com 42 | Action: 43 | - sts:AssumeRole 44 | Path: "/" 45 | Policies: 46 | - PolicyName: ECRpull 47 | PolicyDocument: 48 | Version: "2012-10-17" 49 | Statement: 50 | - Effect: Allow 51 | Action: 52 | - ecr:BatchCheckLayerAvailability 53 | - ecr:BatchGetImage 54 | - ecr:GetDownloadUrlForLayer 55 | - ecr:GetAuthorizationToken 56 | Resource: 57 | - "*" 58 | 59 | InstanceProfile: 60 | Type: AWS::IAM::InstanceProfile 61 | Properties: 62 | Path: "/" 63 | Roles: 64 | - !Ref Role 65 | 66 | LaunchConfiguration: 67 | Type: AWS::AutoScaling::LaunchConfiguration 68 | Metadata: 69 | Comment: "Installs docker as service" 70 | AWS::CloudFormation::Init: 71 | configSets: 72 | default: 73 | - docker 74 | docker: 75 | packages: 76 | yum: 77 | docker: [] 78 | services: 79 | sysvinit: 80 | docker: 81 | enabled: true 82 | ensureRunning: true 83 | Properties: 84 | ImageId: !Ref ImageId 85 | InstanceType: "t2.nano" 86 | IamInstanceProfile: !Ref InstanceProfile 87 | KeyName: !Ref KeyName 88 | UserData: 89 | "Fn::Base64": !Sub 90 | | 91 | #!/bin/bash -xe 92 | 93 | /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchConfiguration --region ${AWS::Region} 94 | docker run -dp 8080:8080 felixb/yocto-httpd 95 | 96 | /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource AutoScalingGroup --region ${AWS::Region} 97 | SecurityGroups: 98 | - !Ref SecurityGroup 99 | 100 | ###### ELB ###### 101 | 102 | SecurityGroupELB: 103 | Type: AWS::EC2::SecurityGroup 104 | Properties: 105 | GroupDescription: "Allow access via http" 106 | VpcId: !ImportValue {"Fn::Sub": "${VPCStackName}-vpc-id"} 107 | SecurityGroupIngress: 108 | - IpProtocol: tcp 109 | FromPort: "80" 110 | ToPort: "80" 111 | CidrIp: "0.0.0.0/0" 112 | Tags: 113 | - Key: Name 114 | Value: !Sub "${TeamName}-yocto-elb" 115 | 116 | ###### auto scaling group ###### 117 | 118 | AutoScalingGroup: 119 | Type: AWS::AutoScaling::AutoScalingGroup 120 | CreationPolicy: 121 | ResourceSignal: 122 | Timeout: PT5M 123 | UpdatePolicy: 124 | AutoScalingRollingUpdate: 125 | MinInstancesInService: "1" 126 | MaxBatchSize: "1" 127 | PauseTime: PT1M 128 | WaitOnResourceSignals: true 129 | Properties: 130 | VPCZoneIdentifier: 131 | - !ImportValue {"Fn::Sub": "${VPCStackName}-subnet-1-public-id"} 132 | - !ImportValue {"Fn::Sub": "${VPCStackName}-subnet-2-public-id"} 133 | - !ImportValue {"Fn::Sub": "${VPCStackName}-subnet-3-public-id"} 134 | LaunchConfigurationName: !Ref LaunchConfiguration 135 | HealthCheckType: "ELB" 136 | HealthCheckGracePeriod: "120" 137 | MinSize: "1" 138 | DesiredCapacity: "1" 139 | MaxSize: "2" 140 | Tags: 141 | - Key: Name 142 | Value: !Sub "${TeamName}-yocto" 143 | PropagateAtLaunch: true 144 | -------------------------------------------------------------------------------- /4cheaters/cloudformation/fargate/cf-templates/resources.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | 3 | Parameters: 4 | VPCStackName: 5 | Type: String 6 | TeamName: 7 | Type: String 8 | 9 | Resources: 10 | 11 | ECSCluster: 12 | Type: AWS::ECS::Cluster 13 | 14 | SecurityGroup: 15 | Type: AWS::EC2::SecurityGroup 16 | Properties: 17 | GroupDescription: "Allow access via http" 18 | VpcId: !ImportValue {"Fn::Sub": "${VPCStackName}-vpc-id"} 19 | SecurityGroupIngress: 20 | - IpProtocol: "tcp" 21 | FromPort: "8080" 22 | ToPort: "8080" 23 | SourceSecurityGroupId: !ImportValue {"Fn::Sub": "${VPCStackName}-alb-sg-id"} 24 | Tags: 25 | - Key: Name 26 | Value: !Sub "${TeamName}-yocto" 27 | 28 | ECSRole: 29 | Type: AWS::IAM::Role 30 | Properties: 31 | RoleName: 'fargate-ecs-role' 32 | AssumeRolePolicyDocument: 33 | Statement: 34 | - Effect: Allow 35 | Principal: 36 | Service: [ecs.amazonaws.com] 37 | Action: ['sts:AssumeRole'] 38 | Path: / 39 | Policies: 40 | - PolicyName: ecs-service-policy 41 | PolicyDocument: 42 | Statement: 43 | - Effect: Allow 44 | Action: 45 | # Rules which allow ECS to attach network interfaces to instances 46 | # on your behalf in order for awsvpc networking mode to work right 47 | - 'ec2:AttachNetworkInterface' 48 | - 'ec2:CreateNetworkInterface' 49 | - 'ec2:CreateNetworkInterfacePermission' 50 | - 'ec2:DeleteNetworkInterface' 51 | - 'ec2:DeleteNetworkInterfacePermission' 52 | - 'ec2:Describe*' 53 | - 'ec2:DetachNetworkInterface' 54 | Resource: '*' 55 | 56 | # This is a role which is used by the ECS tasks themselves. 57 | ECSTaskExecutionRole: 58 | Type: AWS::IAM::Role 59 | Properties: 60 | RoleName: 'fargate-task-role' 61 | AssumeRolePolicyDocument: 62 | Statement: 63 | - Effect: Allow 64 | Principal: 65 | Service: [ecs-tasks.amazonaws.com] 66 | Action: ['sts:AssumeRole'] 67 | Path: / 68 | Policies: 69 | - PolicyName: ecs-task-execution-policy 70 | PolicyDocument: 71 | Statement: 72 | - Effect: Allow 73 | Action: 74 | # Allow the ECS Tasks to download images from ECR 75 | - 'ecr:GetAuthorizationToken' 76 | - 'ecr:BatchCheckLayerAvailability' 77 | - 'ecr:GetDownloadUrlForLayer' 78 | - 'ecr:BatchGetImage' 79 | # Allow task to write metrics 80 | - 'cloudwatch:PutMetricData' 81 | - 'cloudwatch:GetMetricStatistics' 82 | - 'cloudwatch:ListMetrics' 83 | # Allow task to write logs 84 | - 'logs:CreateLogGroup' 85 | - 'logs:CreateLogStream' 86 | - 'logs:PutLogEvents' 87 | Resource: '*' 88 | 89 | # this role is used by autoscaling events 90 | ApplicationAutoScalingRole: 91 | Type: AWS::IAM::Role 92 | Properties: 93 | AssumeRolePolicyDocument: 94 | Statement: 95 | - Effect: Allow 96 | Principal: 97 | Service: 98 | - application-autoscaling.amazonaws.com 99 | Action: 100 | - sts:AssumeRole 101 | Path: "/" 102 | Policies: 103 | - PolicyName: esc-scaling-policy 104 | PolicyDocument: 105 | Statement: 106 | - Effect: Allow 107 | Action: 108 | - ecs:UpdateService 109 | - ecs:DescribeServices 110 | - application-autoscaling:* 111 | - cloudwatch:DescribeAlarms 112 | - cloudwatch:GetMetricStatistics 113 | Resource: "*" 114 | 115 | Outputs: 116 | ClusterName: 117 | Description: The name of the ECS cluster 118 | Value: !Ref 'ECSCluster' 119 | Export: 120 | Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ClusterName' ] ] 121 | ECSTaskExecutionRole: 122 | Description: The ARN of the ECS role 123 | Value: !GetAtt 'ECSTaskExecutionRole.Arn' 124 | Export: 125 | Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ECSTaskExecutionRole' ] ] 126 | ApplicationAutoScalingRole: 127 | Description: The ARN of the ECS Autoscaling role 128 | Value: !GetAtt 'ApplicationAutoScalingRole.Arn' 129 | Export: 130 | Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ApplicationAutoScalingRole' ] ] 131 | SecurityGroup: 132 | Description: A security group used to allow Fargate containers to receive traffic 133 | Value: !Ref 'SecurityGroup' 134 | Export: 135 | Name: !Join [ ':', [ !Ref 'AWS::StackName', 'SecurityGroup' ] ] -------------------------------------------------------------------------------- /4cheaters/cloudformation/lambda/cf-templates/chat-api.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | 4 | Parameters: 5 | TeamName: 6 | Type: String 7 | 8 | Resources: 9 | 10 | ChatApi: 11 | Type: AWS::ApiGateway::RestApi 12 | Properties: 13 | Name: !Sub "chat-api-${TeamName}" 14 | Description: "API used for chatting" 15 | FailOnWarnings : "true" 16 | 17 | ChatApiResource: 18 | Type: AWS::ApiGateway::Resource 19 | Properties: 20 | RestApiId: !Ref ChatApi 21 | ParentId: 22 | Fn::GetAtt: [ChatApi, "RootResourceId"] 23 | PathPart: "chat" 24 | 25 | ###### Read chat ###### 26 | 27 | LambdaReadChatPermissionForApiGateway: 28 | Type: "AWS::Lambda::Permission" 29 | Properties: 30 | Action: "lambda:invokeFunction" 31 | FunctionName: !ImportValue {"Fn::Sub": "lambda-chat-${TeamName}-read-LambdaReadChatArn"} 32 | Principal: "apigateway.amazonaws.com" 33 | SourceArn: 34 | Fn::Join: ["", ["arn:aws:execute-api:", {"Ref": "AWS::Region"}, ":", {"Ref": "AWS::AccountId"}, ":", {"Ref": "ChatApi"}, "/*"]] 35 | 36 | ReadChatRequest: 37 | Type: AWS::ApiGateway::Method 38 | Properties: 39 | AuthorizationType: "NONE" 40 | HttpMethod: "GET" 41 | Integration: 42 | Type: "AWS" 43 | IntegrationHttpMethod: "POST" 44 | Uri: 45 | Fn::Join: ["", ["arn:aws:apigateway:", {"Ref": "AWS::Region"}, ":lambda:path/2015-03-31/functions/", !ImportValue {"Fn::Sub": "lambda-chat-${TeamName}-read-LambdaReadChatArn"}, "/invocations"]] 46 | IntegrationResponses: 47 | - StatusCode: 200 48 | ResourceId: !Ref ChatApiResource 49 | RestApiId: !Ref ChatApi 50 | MethodResponses: 51 | - StatusCode: 200 52 | 53 | ###### Write chat ###### 54 | 55 | LambdaWriteChatPermissionForApiGateway: 56 | Type: "AWS::Lambda::Permission" 57 | Properties: 58 | Action: "lambda:invokeFunction" 59 | FunctionName: !ImportValue {"Fn::Sub": "lambda-chat-${TeamName}-write-LambdaWriteChatArn"} 60 | Principal: "apigateway.amazonaws.com" 61 | SourceArn: 62 | Fn::Join: ["", ["arn:aws:execute-api:", {"Ref": "AWS::Region"}, ":", {"Ref": "AWS::AccountId"}, ":", {"Ref": "ChatApi"}, "/*"]] 63 | 64 | WriteChatRequest: 65 | Type: AWS::ApiGateway::Method 66 | Properties: 67 | AuthorizationType: "NONE" 68 | HttpMethod: "POST" 69 | Integration: 70 | Type: "AWS" 71 | IntegrationHttpMethod: "POST" 72 | Uri: 73 | Fn::Join: ["", ["arn:aws:apigateway:", {"Ref": "AWS::Region"}, ":lambda:path/2015-03-31/functions/", !ImportValue {"Fn::Sub": "lambda-chat-${TeamName}-write-LambdaWriteChatArn"}, "/invocations"]] 74 | IntegrationResponses: 75 | - StatusCode: 200 76 | RequestTemplates: 77 | "application/json": $input.body 78 | ResourceId: !Ref ChatApiResource 79 | RestApiId: !Ref ChatApi 80 | MethodResponses: 81 | - StatusCode: 200 82 | 83 | ###### Api versions ###### 84 | 85 | ApiDeployment: 86 | Type: AWS::ApiGateway::Deployment 87 | DependsOn: [ WriteChatRequest, ReadChatRequest ] 88 | Properties: 89 | RestApiId: !Ref ChatApi 90 | StageName: "TEST" 91 | 92 | ChatApiStage: 93 | DependsOn: [ChatApi] 94 | Type: AWS::ApiGateway::Stage 95 | Properties: 96 | DeploymentId: !Ref ApiDeployment 97 | MethodSettings: 98 | - DataTraceEnabled: true 99 | HttpMethod: "*" 100 | LoggingLevel: "INFO" 101 | ResourcePath: "/*" 102 | RestApiId: !Ref ChatApi 103 | StageName: "LATEST" 104 | 105 | ###### CloudWatch policy ###### 106 | 107 | ApiGatewayCloudWatchLogsRole: 108 | Type: "AWS::IAM::Role" 109 | Properties: 110 | AssumeRolePolicyDocument: 111 | Version: "2012-10-17" 112 | Statement: 113 | - Effect: "Allow" 114 | Principal: 115 | Service: 116 | - "apigateway.amazonaws.com" 117 | Action: 118 | - "sts:AssumeRole" 119 | Path: "/" 120 | Policies: 121 | - PolicyName: "ApiGatewayLogsPolicy" 122 | PolicyDocument: 123 | Version: "2012-10-17" 124 | Statement: 125 | - 126 | Effect: "Allow" 127 | Action: 128 | - "logs:CreateLogGroup" 129 | - "logs:CreateLogStream" 130 | - "logs:DescribeLogGroups" 131 | - "logs:DescribeLogStreams" 132 | - "logs:PutLogEvents" 133 | - "logs:GetLogEvents" 134 | - "logs:FilterLogEvents" 135 | Resource: "*" 136 | 137 | ApiGatewayAccount: 138 | Type: AWS::ApiGateway::Account 139 | Properties: 140 | CloudWatchRoleArn: 141 | Fn::GetAtt: ["ApiGatewayCloudWatchLogsRole", "Arn"] 142 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AWS codelab 2 | Provides aws codelab challenges .. 3 | 4 | ## 1. Preparation 5 | ### 1.1 Tools 6 | - AWS CLI (https://aws.amazon.com/de/cli/) 7 | 8 | ### 1.2 Install tools for cloudformation part 9 | - [Ruby](https://rvm.io/rvm/install), version >=2.0.0 10 | - Ruby header files for building gems with native extensions (`apt-get install ruby-dev` on Ubuntu systems) 11 | - [Bundler](https://bundler.io/): `gem install bundler` 12 | - [autostacker24](https://github.com/AutoScout24/autostacker24): Run `bundle install` in the root directory. 13 | 14 | ### 1.3 Install terraform for terraform part 15 | - [Terraform](https://www.terraform.io/downloads.html) (OSX `brew install terraform`) 16 | 17 | ## 2. EC2 Codelab Challenges 18 | 1. Create DynamoDB to show the general concept of AWS services 19 | 2. Theory EC2 20 | 3. Create VPC 21 | 4. Deploy debug security group 22 | 5. Deploy [yocto](https://github.com/felixb/yocto-httpd) 23 | * auto scaling group 24 | * SSH access 25 | * ELB deployment 26 | * [CF Hint 1](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-elb.html) 27 | * [CF Hint 2](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-group.html) 28 | * [TF Hint 1](https://www.terraform.io/docs/providers/aws/r/elb.html) 29 | * [TF Hint 2](https://www.terraform.io/docs/providers/aws/d/security_group.html) 30 | * Experts would remove the direct instance access via port 8080 now 31 | * Theory DNS 32 | * Create your own DNS entry (optional) 33 | * [CF Hint1](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53-hostedzone.html) 34 | * [CF Hint2](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-recordset.html) 35 | * [TF Hint 1](https://www.terraform.io/docs/providers/aws/d/route53_zone.html) 36 | * [TF Hint 2](https://www.terraform.io/docs/providers/aws/r/route53_record.html) 37 | 6. Autoscaling with [JMeter](http://jmeter.apache.org/download_jmeter.cgi) 38 | * Short introduction to EC2 instance types 39 | * Autoscaling with CloudWatch alarms 40 | * [CF Hint1](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cw-alarm.html) 41 | * [CF Hint2](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-policy.html) 42 | * [TF Hint1](https://www.terraform.io/docs/providers/aws/r/cloudwatch_metric_alarm.html) 43 | * [TF Hint2](https://www.terraform.io/docs/providers/aws/r/autoscaling_policy.html) 44 | 45 | ## 3. Lambda Codelab Challenges 46 | 1. Create DynamoDB to show the general concept of AWS services 47 | 2. Theory Lambda 48 | 3. Deploy hello world example 49 | * Testing 50 | * Make it a real hello world with at least one input parameter 51 | 4. Chat 52 | * Deploy dynamoDb 53 | * Implement, deploy and test read chat lambda 54 | * [Hint1](http://docs.aws.amazon.com/lambda/latest/dg/programming-model.html) 55 | * [Hint2](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html) 56 | * Implement, deploy and test write chat lambda 57 | * [Hint1](http://docs.aws.amazon.com/lambda/latest/dg/programming-model.html) 58 | * [Hint2](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html) 59 | * Deploy and test chat API (only read implemented) 60 | * Implement, deploy and test write API method 61 | * [Hint](http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html#input-variable-reference) 62 | 5. Expert challenge: If you change the dynamoDb table name, it should be at one position (`chat-resources.yaml`). 63 | Currently you have to change it at three positions. 64 | 65 | ## 4. Fargate Codelab Challenges 66 | 1. Theory Fargate 67 | 2. Create VPC 68 | 3. Deploy resources 69 | 4. Deploy [yocto](https://github.com/felixb/yocto-httpd) 70 | * [Hint1](https://docs.aws.amazon.com/de_de/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html) 71 | * [Hint2](https://docs.aws.amazon.com/de_de/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-service.html) 72 | 5. Add an ALB 73 | * [Hint1](https://docs.aws.amazon.com/de_de/AWSCloudFormation/latest/UserGuide/aws-resource-elasticloadbalancingv2-loadbalancer.html) 74 | * [Hint2](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-elasticloadbalancingv2-targetgroup.html) 75 | * [Hint3](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-elasticloadbalancingv2-listenerrule.html) 76 | * Expert: Remove direct access to the service 77 | 6. Add Add Autoscaling with [JMeter](http://jmeter.apache.org/download_jmeter.cgi) 78 | * [Hint1](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-applicationautoscaling-scalabletarget.html) 79 | * [Hint2](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-applicationautoscaling-scalingpolicy.html) 80 | 81 | ## 5. Useful Links: 82 | * AWS Cloudformation Documentation: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html 83 | * AWS IAM Policy Generator: https://awspolicygen.s3.amazonaws.com/policygen.html 84 | * EC2 Instances pricing overview: http://www.ec2instances.info/?region=eu-central-1 85 | -------------------------------------------------------------------------------- /4cheaters/cloudformation/fargate/cf-templates/vpc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: "2010-09-09" 3 | 4 | Parameters: 5 | TeamName: 6 | Type: String 7 | DnsRootDomain: 8 | Type: String 9 | VpcCidr: 10 | Type: String 11 | VpcSubnet1Cidr: 12 | Type: String 13 | VpcSubnet2Cidr: 14 | Type: String 15 | VpcSubnet3Cidr: 16 | Type: String 17 | 18 | Resources: 19 | VPC: 20 | Type: AWS::EC2::VPC 21 | Properties: 22 | CidrBlock: !Ref VpcCidr 23 | EnableDnsSupport: true 24 | EnableDnsHostnames: false 25 | InstanceTenancy: default 26 | Tags: 27 | - Key: Name 28 | Value: !Sub "${TeamName}" 29 | 30 | InternetGateway: 31 | Type: AWS::EC2::InternetGateway 32 | 33 | AttachGateway: 34 | Type: AWS::EC2::VPCGatewayAttachment 35 | Properties: 36 | VpcId: !Ref VPC 37 | InternetGatewayId: !Ref InternetGateway 38 | 39 | RouteTable: 40 | Type: AWS::EC2::RouteTable 41 | Properties: 42 | VpcId: !Ref VPC 43 | Tags: 44 | - Key: Name 45 | Value: !Sub "${TeamName}-route-table-public" 46 | 47 | RoutePublic: 48 | Type: AWS::EC2::Route 49 | Properties: 50 | RouteTableId: !Ref RouteTable 51 | DestinationCidrBlock: 0.0.0.0/0 52 | GatewayId: !Ref InternetGateway 53 | 54 | Subnet1Public: 55 | Type: AWS::EC2::Subnet 56 | Properties: 57 | VpcId: !Ref VPC 58 | MapPublicIpOnLaunch: true 59 | CidrBlock: !Ref VpcSubnet1Cidr 60 | AvailabilityZone: "eu-central-1a" 61 | Tags: 62 | - Key: Name 63 | Value: !Sub "${TeamName}-public-1" 64 | RouteTableAssociation1Public: 65 | Type: AWS::EC2::SubnetRouteTableAssociation 66 | Properties: 67 | SubnetId: !Ref Subnet1Public 68 | RouteTableId: !Ref RouteTable 69 | 70 | Subnet2Public: 71 | Type: AWS::EC2::Subnet 72 | Properties: 73 | VpcId: !Ref VPC 74 | MapPublicIpOnLaunch: true 75 | CidrBlock: !Ref VpcSubnet2Cidr 76 | AvailabilityZone: "eu-central-1b" 77 | Tags: 78 | - Key: Name 79 | Value: !Sub "${TeamName}-public-2" 80 | RouteTableAssociation2Public: 81 | Type: AWS::EC2::SubnetRouteTableAssociation 82 | Properties: 83 | SubnetId: !Ref Subnet2Public 84 | RouteTableId: !Ref RouteTable 85 | 86 | Subnet3Public: 87 | Type: AWS::EC2::Subnet 88 | Properties: 89 | VpcId: !Ref VPC 90 | MapPublicIpOnLaunch: true 91 | CidrBlock: !Ref VpcSubnet3Cidr 92 | AvailabilityZone: "eu-central-1c" 93 | Tags: 94 | - Key: Name 95 | Value: !Sub "${TeamName}-public-3" 96 | RouteTableAssociation3Public: 97 | Type: AWS::EC2::SubnetRouteTableAssociation 98 | Properties: 99 | SubnetId: !Ref Subnet3Public 100 | RouteTableId: !Ref RouteTable 101 | 102 | # ALB settings 103 | SecurityGroupALB: 104 | Type: AWS::EC2::SecurityGroup 105 | Properties: 106 | GroupDescription: Allow access via https 107 | VpcId: !Ref VPC 108 | SecurityGroupIngress: 109 | - IpProtocol: tcp 110 | FromPort: '80' 111 | ToPort: '80' 112 | CidrIp: "0.0.0.0/0" 113 | 114 | ApplicationLoadBalancer: 115 | Type: AWS::ElasticLoadBalancingV2::LoadBalancer 116 | Properties: 117 | Name: !Sub "ALB-${TeamName}" 118 | Subnets: 119 | - !Ref Subnet1Public 120 | - !Ref Subnet2Public 121 | - !Ref Subnet3Public 122 | SecurityGroups: 123 | - !Ref SecurityGroupALB 124 | 125 | DefaultTargetGroup: 126 | Type: "AWS::ElasticLoadBalancingV2::TargetGroup" 127 | Properties: 128 | HealthCheckIntervalSeconds: "5" 129 | HealthCheckPath: "/health" 130 | HealthCheckPort: "8443" 131 | HealthCheckProtocol: "HTTP" 132 | HealthCheckTimeoutSeconds: "2" 133 | HealthyThresholdCount: "2" 134 | Matcher: 135 | HttpCode: "200" 136 | Name: !Sub "${TeamName}-default-targetgroup" 137 | Port: "8443" 138 | Protocol: "HTTP" 139 | UnhealthyThresholdCount: "2" 140 | VpcId: !Ref VPC 141 | 142 | Listener: 143 | Type: "AWS::ElasticLoadBalancingV2::Listener" 144 | Properties: 145 | DefaultActions: 146 | - Type: forward 147 | TargetGroupArn: !Ref DefaultTargetGroup 148 | LoadBalancerArn: !Ref ApplicationLoadBalancer 149 | Port: "80" 150 | Protocol: "HTTP" 151 | 152 | Outputs: 153 | VPCId: 154 | Export: 155 | Name: !Sub "${AWS::StackName}-vpc-id" 156 | Value: !Ref VPC 157 | VPCCidr: 158 | Export: 159 | Name: !Sub "${AWS::StackName}-vpc-cidr" 160 | Value: !Ref VpcCidr 161 | Subnet1PublicId: 162 | Export: 163 | Name: !Sub "${AWS::StackName}-subnet-1-public-id" 164 | Value: !Ref Subnet1Public 165 | Subnet2PublicId: 166 | Export: 167 | Name: !Sub "${AWS::StackName}-subnet-2-public-id" 168 | Value: !Ref Subnet2Public 169 | Subnet3PublicId: 170 | Export: 171 | Name: !Sub "${AWS::StackName}-subnet-3-public-id" 172 | Value: !Ref Subnet3Public 173 | LoadbalancerSecurityGroupId: 174 | Value: !Ref SecurityGroupALB 175 | Export: 176 | Name: !Sub "${AWS::StackName}-alb-sg-id" 177 | LoadbalancerFullname: 178 | Value: !GetAtt ApplicationLoadBalancer.LoadBalancerFullName 179 | Export: 180 | Name: !Sub "${AWS::StackName}-alb-fullname" 181 | ListenerId: 182 | Value: !Ref Listener 183 | Export: 184 | Name: !Sub "${AWS::StackName}-ListenerId" -------------------------------------------------------------------------------- /cloudformation/ec2/jmeter/yocto.jmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | false 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | continue 16 | 17 | false 18 | -1 19 | 20 | 1 21 | 1 22 | 1429602724000 23 | 1429602724000 24 | false 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | yocto.TEAM_NAME.DNS_ROOT_DOMAIN 34 | 35 | http 36 | 37 | 38 | 4 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | / 52 | GET 53 | true 54 | false 55 | true 56 | false 57 | 58 | 59 | 60 | 61 | 62 | 63 | 50 64 | 500 65 | 66 | 67 | 68 | false 69 | 70 | saveConfig 71 | 72 | 73 | true 74 | true 75 | true 76 | 77 | true 78 | true 79 | true 80 | true 81 | false 82 | true 83 | true 84 | false 85 | false 86 | false 87 | false 88 | false 89 | false 90 | false 91 | false 92 | 0 93 | true 94 | true 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | true 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /4cheaters/cloudformation/fargate/cf-templates/service.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | 3 | Parameters: 4 | VPCStackName: 5 | Type: String 6 | ResourcesStackName: 7 | Type: String 8 | TeamName: 9 | Type: String 10 | ServiceName: 11 | Type: String 12 | Default: 'yocto' 13 | Description: A name for the service 14 | ImageUrl: 15 | Type: String 16 | Default: 'felixb/yocto-httpd' 17 | Description: The url of a docker image that contains the application process that 18 | will handle the traffic for this service 19 | ContainerPort: 20 | Type: Number 21 | Default: 8080 22 | Description: What port number the application inside the docker container is binding to 23 | ContainerCpu: 24 | Type: Number 25 | Default: 256 26 | Description: How much CPU to give the container. 1024 is 1 CPU. Max is 10240. 27 | ContainerMemory: 28 | Type: Number 29 | Default: 1024 30 | Description: How much memory in megabytes to give the container 31 | DesiredCount: 32 | Type: Number 33 | Default: 1 34 | Description: How many copies of the service task to run 35 | Path: 36 | Type: String 37 | Default: "/yocto/*" 38 | Description: A path on the public load balancer that this service 39 | should be connected to. Use * to send all load balancer 40 | traffic to this service. 41 | Priority: 42 | Type: Number 43 | Default: 1 44 | Description: The priority for the routing rule added to the load balancer. 45 | This only applies if your have multiple services which have been 46 | assigned to different paths on the load balancer. 47 | 48 | Resources: 49 | CloudwatchLogsGroup: 50 | Type: AWS::Logs::LogGroup 51 | Properties: 52 | LogGroupName: 'yocto' 53 | RetentionInDays: 3 54 | 55 | # The task definition. This is a simple metadata description of what 56 | # container to run, and what resource requirements it has. 57 | # Counterpart in ec2 is the launch configuration 58 | TaskDefinition: 59 | Type: AWS::ECS::TaskDefinition 60 | Properties: 61 | Family: !Ref 'ServiceName' 62 | Cpu: !Ref 'ContainerCpu' 63 | Memory: !Ref 'ContainerMemory' 64 | NetworkMode: awsvpc 65 | RequiresCompatibilities: 66 | - FARGATE 67 | ExecutionRoleArn: !ImportValue {"Fn::Sub": "${ResourcesStackName}:ECSTaskExecutionRole"} 68 | ContainerDefinitions: 69 | - Name: !Ref 'ServiceName' 70 | Cpu: !Ref 'ContainerCpu' 71 | Memory: !Ref 'ContainerMemory' 72 | Image: !Ref 'ImageUrl' 73 | PortMappings: 74 | - 75 | ContainerPort: !Ref 'ContainerPort' 76 | HostPort: !Ref 'ContainerPort' 77 | LogConfiguration: 78 | LogDriver: awslogs 79 | Options: 80 | awslogs-group: !Ref 'CloudwatchLogsGroup' 81 | awslogs-region: 'eu-central-1' 82 | awslogs-stream-prefix: 'yocto' 83 | 84 | 85 | # The service. The service is a resource which allows you to run multiple 86 | # copies of a type of task, and gather up their logs and metrics, as well 87 | # as monitor the number of running tasks and replace any that have crashed 88 | Service: 89 | Type: AWS::ECS::Service 90 | Properties: 91 | ServiceName: !Ref 'ServiceName' 92 | Cluster: !ImportValue {"Fn::Sub": "${ResourcesStackName}:ClusterName"} 93 | LaunchType: FARGATE 94 | DeploymentConfiguration: 95 | MaximumPercent: 200 96 | MinimumHealthyPercent: 75 97 | DesiredCount: !Ref 'DesiredCount' 98 | NetworkConfiguration: 99 | AwsvpcConfiguration: 100 | AssignPublicIp: ENABLED 101 | SecurityGroups: 102 | - !ImportValue {"Fn::Sub": "${ResourcesStackName}:SecurityGroup"} 103 | Subnets: 104 | - !ImportValue {"Fn::Sub": "${VPCStackName}-subnet-1-public-id"} 105 | - !ImportValue {"Fn::Sub": "${VPCStackName}-subnet-2-public-id"} 106 | TaskDefinition: !Ref 'TaskDefinition' 107 | LoadBalancers: 108 | - ContainerName: !Ref 'ServiceName' 109 | ContainerPort: !Ref 'ContainerPort' 110 | TargetGroupArn: !Ref 'TargetGroup' 111 | 112 | # A target group. This is used for keeping track of all the tasks, and 113 | # what IP addresses / port numbers they have. You can query it yourself, 114 | # to use the addresses yourself, but most often this target group is just 115 | # connected to an application load balancer, or network load balancer, so 116 | # it can automatically distribute traffic across all the targets. 117 | TargetGroup: 118 | Type: AWS::ElasticLoadBalancingV2::TargetGroup 119 | Properties: 120 | HealthCheckIntervalSeconds: 5 121 | HealthCheckPath: '/status' 122 | HealthCheckProtocol: HTTP 123 | HealthCheckTimeoutSeconds: 2 124 | HealthyThresholdCount: 2 125 | TargetType: ip 126 | Name: !Ref 'ServiceName' 127 | Port: !Ref 'ContainerPort' 128 | Protocol: HTTP 129 | UnhealthyThresholdCount: 2 130 | VpcId: !ImportValue {"Fn::Sub": "${VPCStackName}-vpc-id"} 131 | 132 | 133 | # Create a rule on the load balancer for routing traffic to the target group 134 | LoadBalancerRule: 135 | Type: AWS::ElasticLoadBalancingV2::ListenerRule 136 | Properties: 137 | Actions: 138 | - TargetGroupArn: !Ref 'TargetGroup' 139 | Type: 'forward' 140 | Conditions: 141 | - Field: path-pattern 142 | Values: [!Ref 'Path'] 143 | ListenerArn: !ImportValue {"Fn::Sub": "${VPCStackName}-ListenerId"} 144 | Priority: !Ref 'Priority' 145 | 146 | ScalableTarget: 147 | Type: AWS::ApplicationAutoScaling::ScalableTarget 148 | Properties: 149 | MaxCapacity: 3 150 | MinCapacity: 1 151 | ResourceId: !Join [ "/", [ "service", !ImportValue {"Fn::Sub": "${ResourcesStackName}:ClusterName"}, !GetAtt Service.Name ] ] 152 | RoleARN: 153 | Fn::ImportValue: 154 | !Join [':', [!Ref 'ResourcesStackName', 'ApplicationAutoScalingRole']] 155 | ScalableDimension: ecs:service:DesiredCount 156 | ServiceNamespace: ecs 157 | 158 | AutoScalingPolicy: 159 | Type: AWS::ApplicationAutoScaling::ScalingPolicy 160 | Properties: 161 | PolicyName: ECSScalingBlogPolicy 162 | PolicyType: TargetTrackingScaling 163 | ScalingTargetId: 164 | Ref: ScalableTarget 165 | ScalableDimension: ecs:service:DesiredCount 166 | ServiceNamespace: ecs 167 | TargetTrackingScalingPolicyConfiguration: 168 | TargetValue: 10.0 169 | ##Time waiting between adding new instances 170 | ScaleOutCooldown: 20 171 | ##Time waiting between removing old instances 172 | ScaleInCooldown: 60 173 | PredefinedMetricSpecification: 174 | PredefinedMetricType: ALBRequestCountPerTarget 175 | ResourceLabel: !Join [ "/", [ !ImportValue {"Fn::Sub": "${VPCStackName}-alb-fullname"}, !GetAtt TargetGroup.TargetGroupFullName] ] -------------------------------------------------------------------------------- /cloudformation/fargate/jmeter/yocto.jmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | false 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | continue 16 | 17 | false 18 | -1 19 | 20 | 1 21 | 1 22 | 1429602724000 23 | 1429602724000 24 | false 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | alb-foobar-1158200659.eu-central-1.elb.amazonaws.com 34 | 35 | 36 | 37 | /yocto/status 38 | GET 39 | true 40 | false 41 | true 42 | false 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 50 | 500 51 | 52 | 53 | 54 | false 55 | 56 | saveConfig 57 | 58 | 59 | true 60 | true 61 | true 62 | 63 | true 64 | true 65 | true 66 | true 67 | false 68 | true 69 | true 70 | false 71 | false 72 | false 73 | false 74 | false 75 | false 76 | false 77 | false 78 | 0 79 | true 80 | true 81 | 82 | 83 | 84 | 85 | 86 | 87 | false 88 | 89 | saveConfig 90 | 91 | 92 | true 93 | true 94 | true 95 | 96 | true 97 | true 98 | true 99 | true 100 | false 101 | true 102 | true 103 | false 104 | false 105 | false 106 | true 107 | false 108 | false 109 | false 110 | true 111 | 0 112 | true 113 | true 114 | true 115 | true 116 | true 117 | true 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /4cheaters/cloudformation/ec2/cf-templates/vpc-yocto.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: "2010-09-09" 3 | 4 | Parameters: 5 | VPCStackName: 6 | Type: String 7 | TeamName: 8 | Type: String 9 | ImageId: 10 | Type: String 11 | KeyName: 12 | Type: String 13 | 14 | Resources: 15 | 16 | ###### EC2 instance ###### 17 | 18 | SecurityGroup: 19 | Type: AWS::EC2::SecurityGroup 20 | Properties: 21 | GroupDescription: "Allow access via http" 22 | VpcId: !ImportValue {"Fn::Sub": "${VPCStackName}-vpc-id"} 23 | SecurityGroupIngress: 24 | - IpProtocol: "tcp" 25 | FromPort: "8080" 26 | ToPort: "8080" 27 | CidrIp: "172.16.0.0/16" 28 | Tags: 29 | - Key: Name 30 | Value: !Sub "${TeamName}-yocto" 31 | 32 | Role: 33 | Type: AWS::IAM::Role 34 | Properties: 35 | AssumeRolePolicyDocument: 36 | Version: "2012-10-17" 37 | Statement: 38 | - Effect: Allow 39 | Principal: 40 | Service: 41 | - ec2.amazonaws.com 42 | Action: 43 | - sts:AssumeRole 44 | Path: "/" 45 | Policies: 46 | - PolicyName: ECRpull 47 | PolicyDocument: 48 | Version: "2012-10-17" 49 | Statement: 50 | - Effect: Allow 51 | Action: 52 | - ecr:BatchCheckLayerAvailability 53 | - ecr:BatchGetImage 54 | - ecr:GetDownloadUrlForLayer 55 | - ecr:GetAuthorizationToken 56 | Resource: 57 | - "*" 58 | 59 | InstanceProfile: 60 | Type: AWS::IAM::InstanceProfile 61 | Properties: 62 | Path: "/" 63 | Roles: 64 | - !Ref Role 65 | 66 | LaunchConfiguration: 67 | Type: AWS::AutoScaling::LaunchConfiguration 68 | Metadata: 69 | Comment: "Installs docker as service" 70 | AWS::CloudFormation::Init: 71 | configSets: 72 | default: 73 | - docker 74 | docker: 75 | packages: 76 | yum: 77 | docker: [] 78 | services: 79 | sysvinit: 80 | docker: 81 | enabled: true 82 | ensureRunning: true 83 | Properties: 84 | ImageId: !Ref ImageId 85 | InstanceType: "t2.nano" 86 | IamInstanceProfile: !Ref InstanceProfile 87 | KeyName: !Ref KeyName 88 | UserData: 89 | "Fn::Base64": !Sub 90 | | 91 | #!/bin/bash -xe 92 | 93 | /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchConfiguration --region ${AWS::Region} 94 | docker run -dp 8080:8080 felixb/yocto-httpd 95 | 96 | /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource AutoScalingGroup --region ${AWS::Region} 97 | SecurityGroups: 98 | - !Ref SecurityGroup 99 | 100 | ###### ELB ###### 101 | 102 | SecurityGroupELB: 103 | Type: AWS::EC2::SecurityGroup 104 | Properties: 105 | GroupDescription: "Allow access via http" 106 | VpcId: !ImportValue {"Fn::Sub": "${VPCStackName}-vpc-id"} 107 | SecurityGroupIngress: 108 | - IpProtocol: tcp 109 | FromPort: "80" 110 | ToPort: "80" 111 | CidrIp: "0.0.0.0/0" 112 | Tags: 113 | - Key: Name 114 | Value: !Sub "${TeamName}-yocto-elb" 115 | 116 | YoctoElasticLoadBalancer: 117 | Type: AWS::ElasticLoadBalancing::LoadBalancer 118 | Properties: 119 | LoadBalancerName: !Sub "${TeamName}-yocto-elb" 120 | Subnets: 121 | - !ImportValue {"Fn::Sub": "${VPCStackName}-subnet-1-public-id"} 122 | - !ImportValue {"Fn::Sub": "${VPCStackName}-subnet-2-public-id"} 123 | - !ImportValue {"Fn::Sub": "${VPCStackName}-subnet-3-public-id"} 124 | SecurityGroups: 125 | - !Ref SecurityGroupELB 126 | CrossZone: true 127 | Listeners: 128 | - LoadBalancerPort: "80" 129 | InstancePort: "8080" 130 | Protocol: HTTP 131 | HealthCheck: 132 | Target: HTTP:8080/status 133 | HealthyThreshold: "2" 134 | UnhealthyThreshold: "2" 135 | Interval: "5" 136 | Timeout: "2" 137 | 138 | DNSRecord: 139 | Type: AWS::Route53::RecordSet 140 | Properties: 141 | Comment: "DNS name" 142 | HostedZoneId: !ImportValue {"Fn::Sub": "${VPCStackName}-hosted-zone-id"} 143 | Name: !Join [ "", [ "yocto.", !ImportValue {"Fn::Sub": "${VPCStackName}-hosted-zone-name"} ] ] 144 | Type: "A" 145 | AliasTarget: 146 | HostedZoneId: !GetAtt YoctoElasticLoadBalancer.CanonicalHostedZoneNameID 147 | DNSName: !GetAtt YoctoElasticLoadBalancer.DNSName 148 | 149 | ###### auto scaling group ###### 150 | 151 | AutoScalingGroup: 152 | Type: AWS::AutoScaling::AutoScalingGroup 153 | CreationPolicy: 154 | ResourceSignal: 155 | Timeout: PT5M 156 | UpdatePolicy: 157 | AutoScalingRollingUpdate: 158 | MinInstancesInService: "1" 159 | MaxBatchSize: "1" 160 | PauseTime: PT1M 161 | WaitOnResourceSignals: true 162 | DependsOn: 163 | - YoctoElasticLoadBalancer 164 | Properties: 165 | LoadBalancerNames: 166 | - !Sub "${TeamName}-yocto-elb" 167 | VPCZoneIdentifier: 168 | - !ImportValue {"Fn::Sub": "${VPCStackName}-subnet-1-public-id"} 169 | - !ImportValue {"Fn::Sub": "${VPCStackName}-subnet-2-public-id"} 170 | - !ImportValue {"Fn::Sub": "${VPCStackName}-subnet-3-public-id"} 171 | LaunchConfigurationName: !Ref LaunchConfiguration 172 | HealthCheckType: "ELB" 173 | HealthCheckGracePeriod: "120" 174 | MinSize: "1" 175 | DesiredCapacity: "1" 176 | MaxSize: "2" 177 | Tags: 178 | - Key: Name 179 | Value: !Sub "${TeamName}-yocto" 180 | PropagateAtLaunch: true 181 | 182 | ScaleUpPolicy: 183 | Type: AWS::AutoScaling::ScalingPolicy 184 | Properties: 185 | AdjustmentType: "ChangeInCapacity" 186 | AutoScalingGroupName: !Ref AutoScalingGroup 187 | Cooldown: "180" 188 | ScalingAdjustment: "1" 189 | 190 | ScaleDownPolicy: 191 | Type: AWS::AutoScaling::ScalingPolicy 192 | Properties: 193 | AdjustmentType: "ChangeInCapacity" 194 | AutoScalingGroupName: !Ref AutoScalingGroup 195 | Cooldown: "180" 196 | ScalingAdjustment: "-1" 197 | 198 | AlarmRequestCountHigh: 199 | Type: AWS::CloudWatch::Alarm 200 | Properties: 201 | AlarmName: !Sub "${TeamName}-Yocto request count too high" 202 | EvaluationPeriods: "1" 203 | Statistic: "Sum" 204 | Threshold: "100" 205 | Period: "60" 206 | AlarmActions: 207 | - Ref: ScaleUpPolicy 208 | Namespace: "AWS/ELB" 209 | Dimensions: 210 | - Name: LoadBalancerName 211 | Value: !Sub "${TeamName}-yocto-elb" 212 | ComparisonOperator: "GreaterThanThreshold" 213 | MetricName: "RequestCount" 214 | 215 | AlarmRequestCountLow: 216 | Type: AWS::CloudWatch::Alarm 217 | Properties: 218 | AlarmName: !Sub "${TeamName}-Yocto request count too low" 219 | EvaluationPeriods: "1" 220 | Statistic: "Sum" 221 | Threshold: "5" 222 | Period: "60" 223 | AlarmActions: 224 | - Ref: ScaleDownPolicy 225 | Namespace: "AWS/ELB" 226 | Dimensions: 227 | - Name: LoadBalancerName 228 | Value: !Sub "${TeamName}-yocto-elb" 229 | ComparisonOperator: "LessThanThreshold" 230 | MetricName: "RequestCount" 231 | --------------------------------------------------------------------------------