Skip to content
This repository has been archived by the owner on Sep 25, 2020. It is now read-only.

SpotFleet CloudFormation #69

Merged
merged 15 commits into from
Jun 26, 2017
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,46 @@ application/config/environments/*.local.yml
.DS_Store
.AppleDouble
.LSOverride

### https://raw.github.com/github/gitignore/9f6724149b9a0a861b402683f6c50c5f085d130b/node.gitignore

# Logs
logs
*.log
npm-debug.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules
jspm_packages

# Optional npm cache directory
.npm

# Optional REPL history
.node_repl_history

infrastructure/**/built
7 changes: 7 additions & 0 deletions infrastructure/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## How to Deploy

```bash
# BUCKET_NAME is used for `aws cloudformation package`
# STACK_NAME is used for `aws cloudformation deploy`
$ BUCKET_NAME=bucket-name STACK_NAME=stack-name bin/deploy
```
30 changes: 30 additions & 0 deletions infrastructure/bin/deploy
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash

if [ -z "$BUCKET_NAME" ]; then
echo 'BUCKET_NAME is required'
exit 1
fi

if [ -z "$STACK_NAME" ]; then
echo 'STACK_NAME is required'
exit 1
fi

TEMPLATE_FILE=cloudformation.yml

# Move project root
cd "$(dirname "$(perl -e 'use Cwd "abs_path";print abs_path(shift)' "$0")")/.." || exit 1

sh -c 'cd ./functions/RunEcsTask && npm install && npm run build && cp -rf ./node_modules ./built/'

mkdir -p ./built

aws cloudformation package \
--template-file "$TEMPLATE_FILE" \
--output-template-file ./built/cloudformation.yml \
--s3-bucket "$BUCKET_NAME"

aws cloudformation deploy \
--capabilities CAPABILITY_NAMED_IAM \
--template-file built/cloudformation.yml \
--stack-name "$STACK_NAME"
176 changes: 176 additions & 0 deletions infrastructure/cloudformation.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: revieee development settings
Resources:

Expand Down Expand Up @@ -163,6 +164,28 @@ Resources:
Properties:
ClusterName: !Join [ "-", [ !Ref "AWS::StackName", RevieeeCluster ] ]

# SpotFleet
EcsSpotFleetRequest:
Type: AWS::EC2::SpotFleet
Properties:
SpotFleetRequestConfigData:
IamFleetRole: !GetAtt [IAMFleetRole, Arn]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

=> IAMFleetRole.Arn

SpotPrice: '0.139'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このあたりはパラメータ設定出来るようにする!

TargetCapacity: '2'
LaunchSpecifications:
- EbsOptimized: 'false'
InstanceType: 'm4.large'
ImageId: 'ami-3a000e5d'
SubnetId:
Ref: ContainerInstanceSubnet1a
WeightedCapacity: '4'
- EbsOptimizes: 'false'
InstanceType: 'm3.large'
ImageId: 'ami-3a000e5d'
SubnetId:
Ref: ContainerInstanceSubnet1c
WeightedCapacity: '1'

EndpointInstanceIamRole:
Type: AWS::IAM::Role
Properties:
Expand Down Expand Up @@ -199,6 +222,159 @@ Resources:
Value: RevieeeEndpointInstance
# UserData: [TODO] run itamae

# ------ API Gateway ------

ApiRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
-
Effect: Allow
Principal:
Service:
- apigateway.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: "states:*"
Resource: "*"
PolicyName: !Join [ "-", [ !Ref "AWS::StackName", AWSStepFunctionsFullAccess ] ]
RoleName: !Join [ "-", [ !Ref "AWS::StackName", RevieeeApiRole ] ]

RevieeeApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: !Join [ "-", [ !Ref "AWS::StackName", RevieeeApi ] ]
RevieeeApiResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref RevieeeApi
ParentId: !GetAtt RevieeeApi.RootResourceId
PathPart: "stage"
RevieeeApiCreateMethod:
Type: AWS::ApiGateway::Method
Properties:
RestApiId: !Ref RevieeeApi
ResourceId: !Ref RevieeeApiResource
AuthorizationType: NONE
HttpMethod: POST
Integration:
IntegrationHttpMethod: POST
IntegrationResponses:
- StatusCode: 200
PassthroughBehavior: WHEN_NO_TEMPLATES
RequestTemplates:
application/json: !Sub
- |-
{
"input": "{}",
"name": "Hello",
"stateMachineArn": "${stateMachineArn}"
}
- { stateMachineArn: !Ref StateMachineCreate }
Type: AWS
Uri: !Join [ "", [ "arn:aws:apigateway:", !Ref "AWS::Region", ":states:action/StartExecution" ] ]
Credentials: !GetAtt ApiRole.Arn
MethodResponses:
- StatusCode: 200
ApiDeployment:
Type: AWS::ApiGateway::Deployment
DependsOn: RevieeeApiCreateMethod
Properties:
RestApiId: !Ref RevieeeApi
StageName: pub

# ------ /API Gateway ------

# ------ StepFunctions ------

StateMachineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
-
Effect: Allow
Principal:
Service:
- states.ap-northeast-1.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: "lambda:InvokeFunction"
Resource: "*"
PolicyName: !Join [ "-", [ !Ref "AWS::StackName", StatesExecutionPolicy ] ]
RoleName: !Join [ "-", [ !Ref "AWS::StackName", RevieeeStateMachineRole ] ]

StateMachineCreate:
Type: AWS::StepFunctions::StateMachine
Properties:
DefinitionString: !Sub
- |-
{
"Comment": "Run ECS Task",
"StartAt": "RunEcsTask",
"States": {
"RunEcsTask": {
"Type": "Task",
"Resource": "${taskArn}",
"End": true
}
}
}
- { "taskArn": !Ref RunEcsTaskFunction }
RoleArn: !GetAtt StateMachineRole.Arn

# ------ /StepFunctions ------

# ------ Lambda ------

RunEcsTaskFunctionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
-
Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: "ecs:RunTask"
Resource: "*"
PolicyName: !Join [ "-", [ !Ref "AWS::StackName", RunEcsTaskFunctionPolicy ] ]
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
RoleName: !Join [ "-", [ !Ref "AWS::StackName", RevieeeRunEcsTaskFunctionRole ] ]

RunEcsTaskFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs6.10
CodeUri: ./functions/RunEcsTask/built/
Role: !GetAtt RunEcsTaskFunctionRole.Arn

# ------ /Lambda ------

# Parameter
Parameters:
SSHPort:
Expand Down
23 changes: 23 additions & 0 deletions infrastructure/functions/RunEcsTask/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "run-ecs-task",
"version": "0.0.1",
"description": "Lambda function that to run ECS Task",
"main": "index.js",
"scripts": {
"build": "tsc -p ./tsconfig.json",
"clean": "rm -rf ./built"
},
"author": "",
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/speee/webapp-revieee"
},
"devDependencies": {
"@types/aws-lambda": "0.0.12",
"@types/node": "^7.0.31",
"aws-sdk": "^2.71.0",
"tslint": "^5.4.3",
"typescript": "^2.3.4"
}
}
32 changes: 32 additions & 0 deletions infrastructure/functions/RunEcsTask/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Callback, Context } from "aws-lambda";
import * as AWS from "aws-sdk";

const ecs = new AWS.ECS();

export function handler(event: any, context: Context, callback: Callback) {
const envBranch: AWS.ECS.KeyValuePair = {
name: "BRANCH",
value: "master",
};
const containerOverride: AWS.ECS.ContainerOverride = {
name: "main",
environment: [envBranch],
};
const taskOverride: AWS.ECS.TaskOverride = {
containerOverrides: [containerOverride],
};
const params: AWS.ECS.RunTaskRequest = {
cluster: "revieee",
taskDefinition: "arn:aws:ecs:ap-northeast-1:951787653356:task-definition/im-ieul-core:3",
overrides: taskOverride,
};

(async () => {
return await ecs.runTask(params).promise();
})().then((result: AWS.ECS.RunTaskResponse) => {
console.log(result.tasks);
callback(null, result.tasks[0].taskArn);
}).catch((err: AWS.AWSError) => {
callback(err);
});
}
14 changes: 14 additions & 0 deletions infrastructure/functions/RunEcsTask/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"noImplicitAny": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"outDir": "./built",
"allowJs": true
},
"include": [
"./src/**/*"
]
}
Loading