founders_template 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile-rails6.lock +1 -1
  3. data/lib/founders_template/cli.rb +35 -4
  4. data/lib/founders_template/config_file.rb +11 -2
  5. data/lib/founders_template/version.rb +1 -1
  6. data/templates/Dockerfile.erb +68 -0
  7. data/templates/docker/nginx/nginx.conf +78 -0
  8. data/templates/docker-compose.yml.erb +75 -0
  9. data/templates/terraform/modules/application/main.tf +70 -0
  10. data/templates/terraform/modules/application/one_off_service.tf +48 -0
  11. data/templates/terraform/modules/application/outputs.tf +19 -0
  12. data/templates/terraform/modules/application/policies/ecs_execution.json +17 -0
  13. data/templates/terraform/modules/application/policies/ecs_execution_role.json +21 -0
  14. data/templates/terraform/modules/application/policies/ecs_task_execution.json +17 -0
  15. data/templates/terraform/modules/application/sshable.tf +17 -0
  16. data/templates/terraform/modules/application/task_definitions/one_off.json +18 -0
  17. data/templates/terraform/modules/application/task_definitions/web.json +41 -0
  18. data/templates/terraform/modules/application/task_definitions/worker.json +49 -0
  19. data/templates/terraform/modules/application/variables.tf +109 -0
  20. data/templates/terraform/modules/application/web_service.tf +62 -0
  21. data/templates/terraform/modules/application/worker_service.tf +48 -0
  22. data/templates/terraform/production/domains.tf +19 -0
  23. data/templates/terraform/production/main.tf +167 -0
  24. data/templates/terraform/production/ssl.tf +28 -0
  25. data/templates/terraform/production/variables.tf +36 -0
  26. data/templates/terraform/shared/main.tf +41 -0
  27. data/templates/terraform/shared/terraform.tfstate.backup +129 -0
  28. data/templates/terraform-production.tfvars.erb +4 -0
  29. data/templates/terraform-shared.tfvars.erb +1 -0
  30. metadata +26 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b5f2681dabadc9894661a24323ba46dd5f4a95a6b80080762bbacc6d27779f84
4
- data.tar.gz: d4a66020be8435a346e9151de52dbfa183ec2b0d7ff409eb3fe67f70a1bb04d2
3
+ metadata.gz: 63513b1a9939d9994e19c59956425304098c38aa841d358da7d873676a1e95e7
4
+ data.tar.gz: 1cc583c8e56bfca7894d0b879b179fa4ce804d0dca3386e3a3620ff40a1afa16
5
5
  SHA512:
6
- metadata.gz: f073af7c2e910ab1058d222cb52064898b7d2cef2fbed888e38380411ca4829c8866474b9a9f5eb9b2540ac72d5dc960ca29a246a7076cb097c0a14290b6bece
7
- data.tar.gz: 411810e4b15c74221fd7e5cb8215cea6e4a78943107289f8db2a28b42228746a6a0a0d8fc97c146447c463d8dd2514c9d41a241d17ac8f61378e9e6241982e2c
6
+ metadata.gz: 025e9454595dd45dcf5b40281ac4eac1f8f547cbd77265610e5252b0c20e9a4e2e692cd679e2c24823505a9c2ab184072127cda95962939df5670d772c3ee3cf
7
+ data.tar.gz: 9ed501799e1a6b1a5903caed3ce0b403a2f70afafaf662ab202f5d6ae2a2676cda90c2bc4900da20c7e098716865ba20e5211cdc52cab43a5f980cf6588d6f30
data/Gemfile-rails6.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- founders_template (0.1.8)
4
+ founders_template (0.2.0)
5
5
  activesupport
6
6
  aws-sdk-core
7
7
  aws-sdk-ec2
@@ -52,8 +52,13 @@ module FoundersTemplate
52
52
  template 'buildspec.yml.erb', 'buildspec.yml'
53
53
  template 'dockerignore.erb', '.dockerignore'
54
54
  template 'docker-compose.ci.yml.erb', 'docker-compose.ci.yml'
55
+ template 'docker-compose.yml.erb', 'docker-compose.yml'
55
56
  template 'docker-sync.yml.erb', 'docker-sync.yml'
57
+ template 'Dockerfile.erb', 'Dockerfile'
56
58
 
59
+ install_terraform_project
60
+
61
+ directory 'docker', 'docker'
57
62
  directory 'ci', 'ci'
58
63
  end
59
64
 
@@ -63,6 +68,23 @@ module FoundersTemplate
63
68
  VERSION
64
69
  end
65
70
 
71
+ def install_terraform_project
72
+ directory 'terraform', 'terraform'
73
+
74
+ template 'terraform-production.tfvars.erb', 'terraform/production/terraform.tfvars'
75
+ template 'terraform-shared.tfvars.erb', 'terraform/shared/terraform.tfvars'
76
+
77
+ gsub_file 'terraform/production/main.tf',
78
+ /(bucket\s+=\s+)".+-terraform-production"/,
79
+ %(\\1"#{app_config.slugified_name}-terraform-production")
80
+ gsub_file 'terraform/production/main.tf',
81
+ /(dynamodb_table\s+=\s+)".+-terraform-production"/,
82
+ %(\\1"#{app_config.slugified_name}-terraform-production")
83
+ gsub_file 'terraform/production/main.tf',
84
+ /(region\s+=\s+)".+"/,
85
+ %(\\1"#{app_config.aws_region}")
86
+ end
87
+
66
88
  def ensure_aws_credentials
67
89
  return if aws_credentials?
68
90
 
@@ -88,6 +110,7 @@ module FoundersTemplate
88
110
  default: 'us-east-1'
89
111
 
90
112
  add_to_envrc AWS_REGION: aws_region
113
+ add_to_envrc AWS_DEFAULT_REGION: aws_region
91
114
 
92
115
  profile = <<~TEXT
93
116
  [#{app_config.short_name}]
@@ -168,10 +191,18 @@ module FoundersTemplate
168
191
  end
169
192
 
170
193
  def ensure_application_config
171
- return if app_config.valid?
172
-
173
- app_config.name = ask 'Application Name:'
174
- app_config.short_name = ask 'Application Short Name:', default: app_config.short_name
194
+ unless app_config.name
195
+ app_config.name = ask 'Application Name:'
196
+ app_config.short_name = ask 'Application Short Name:', default: app_config.short_name
197
+ end
198
+
199
+ app_config.github_org = ask 'GitHub Organization:' unless app_config.github_org
200
+ app_config.github_repo = ask 'GitHub Repo Name:' unless app_config.github_repo
201
+
202
+ unless app_config.valid?
203
+ error 'There is an error in your config.'
204
+ exit 1
205
+ end
175
206
 
176
207
  template_file app_config
177
208
  end
@@ -1,20 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'founders_template/template_file'
4
+ require 'active_support/core_ext/string/inflections'
4
5
 
5
6
  module FoundersTemplate
6
7
  class ConfigFile < TemplateFile
7
8
  root_key 'application'
8
- required_keys %i( name short_name )
9
+ required_keys %i( name short_name github_org github_repo)
9
10
 
10
11
  template_file 'ft.yml.erb'
11
12
  output_file 'ft.yml'
12
13
 
13
- attr_accessor :name
14
+ attr_accessor :name, :github_org, :github_repo
14
15
  attr_writer :short_name
15
16
 
16
17
  def short_name
17
18
  @short_name ||= name.split.map(&:chr).join.downcase
18
19
  end
20
+
21
+ def slugified_name
22
+ name.parameterize
23
+ end
24
+
25
+ def aws_region
26
+ ENV['AWS_REGION']
27
+ end
19
28
  end
20
29
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FoundersTemplate
4
- VERSION = '0.1.8'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -0,0 +1,68 @@
1
+ FROM ruby:2.6.5-alpine as builder
2
+
3
+ RUN apk add --update --no-cache \
4
+ build-base \
5
+ postgresql-dev \
6
+ git \
7
+ yarn \
8
+ tzdata \
9
+ vim \
10
+ less
11
+
12
+ WORKDIR /app
13
+
14
+ COPY Gemfile* ./
15
+ COPY vendor ./vendor/
16
+
17
+ ARG RAILS_ENV=development
18
+ ENV RAILS_ENV=$RAILS_ENV
19
+
20
+ RUN if [ "$RAILS_ENV" = "production" ] || [ "$RAILS_ENV" = "staging" ]; then bundle install --jobs 4 --deployment --without development test; else bundle install --jobs 4 --path vendor/bundle; fi
21
+
22
+ COPY package.json* ./
23
+ COPY yarn.lock ./
24
+ RUN yarn install
25
+
26
+ COPY . /app
27
+
28
+ ARG SECRET_KEY_BASE
29
+ ENV SECRET_KEY_BASE=$SECRET_KEY_BASE
30
+
31
+ ARG DATABASE_URL="postgres://postgres@db"
32
+ ENV DATABASE_URL=$DATABASE_URL
33
+
34
+ ARG REDIS_URL="redis://redis"
35
+ ENV REDIS_URL=$REDIS_URL
36
+
37
+ ARG AWS_DEFAULT_REGION
38
+ ARG AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
39
+ ARG COMPILE_ASSETS
40
+ RUN if [ ! -z "$COMPILE_ASSETS" ] || [ "$RAILS_ENV" = "production" ] || [ "$RAILS_ENV" = "staging" ]; then ASSET_COMPILATION=1 bundle exec rake assets:precompile; fi
41
+
42
+ ENTRYPOINT [ "bundle", "exec" ]
43
+
44
+ # App
45
+ FROM builder as app
46
+
47
+ ENV RAILS_LOG_TO_STDOUT=1
48
+
49
+ ARG RAILS_MASTER_KEY
50
+ RUN if [ ! -z "$RAILS_MASTER_KEY" ] ; then echo "$RAILS_MASTER_KEY" > config/credentials/$RAILS_ENV.key ; fi
51
+
52
+ ENV EDITOR=vim
53
+ ENTRYPOINT [ "bundle", "exec" ]
54
+
55
+ # Web
56
+ FROM nginx as web
57
+
58
+ WORKDIR /app
59
+
60
+ COPY --from=builder /app/public /app/public/
61
+ COPY docker/nginx/nginx.conf /etc/nginx/conf.d/default.conf
62
+
63
+ ARG RAILS_ENV=development
64
+ RUN if [ "$RAILS_ENV" = "production" ]; then sed -i 's/app:3000/localhost:3000/' /etc/nginx/conf.d/default.conf; fi
65
+
66
+ EXPOSE 80
67
+
68
+ CMD [ "nginx", "-g", "daemon off;" ]
@@ -0,0 +1,78 @@
1
+ upstream rails_app {
2
+ server app:3000;
3
+ }
4
+
5
+ server {
6
+ # define your domain
7
+ server_name www.example.com;
8
+
9
+ gzip on;
10
+ gzip_proxied no-cache no-store private expired auth;
11
+ gzip_min_length 1024;
12
+ gzip_types text/plain text/css application/json application/x-javascript text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;
13
+
14
+ client_max_body_size 50M;
15
+
16
+ # define the public application root
17
+ root /app/public;
18
+ index index.html;
19
+
20
+ # define where Nginx should write its logs
21
+ access_log /dev/stdout;
22
+ error_log /dev/stderr;
23
+
24
+ # deny requests for files that should never be accessed
25
+ location ~ /\. {
26
+ deny all;
27
+ }
28
+ location ~* ^.+\.(rb|log)$ {
29
+ deny all;
30
+ }
31
+
32
+ # serve static (compiled) assets directly if they exist (for rails production)
33
+ location ~* ^/(packs|assets)/ {
34
+ try_files $uri @rails;
35
+
36
+ access_log off;
37
+ gzip_static on;
38
+ expires max;
39
+
40
+ add_header Cache-Control public;
41
+ add_header Last-Modified "";
42
+ add_header ETag "";
43
+
44
+ add_header 'Access-Control-Allow-Origin' '*';
45
+ add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
46
+ add_header 'Access-Control-Expose-Headers' '';
47
+ add_header 'Access-Control-Max-Age' 1728000;
48
+
49
+ break;
50
+ }
51
+
52
+ # ActionCable config
53
+ location /cable {
54
+ proxy_http_version 1.1;
55
+ proxy_redirect off;
56
+
57
+ proxy_set_header Upgrade $http_upgrade;
58
+ proxy_set_header Connection "Upgrade";
59
+ proxy_set_header X-Real-IP $remote_addr;
60
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
61
+ proxy_set_header Host $http_host;
62
+
63
+ proxy_pass http://rails_app;
64
+ }
65
+
66
+ # send non-static file requests to the app server
67
+ location / {
68
+ try_files $uri @rails;
69
+ }
70
+
71
+ location @rails {
72
+ proxy_set_header X-Real-IP $remote_addr;
73
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
74
+ proxy_set_header Host $http_host;
75
+ proxy_redirect off;
76
+ proxy_pass http://rails_app;
77
+ }
78
+ }
@@ -0,0 +1,75 @@
1
+ version: '3.4'
2
+
3
+ volumes:
4
+ <%= app_config.short_name %>:
5
+ external: true
6
+
7
+ services:
8
+ web:
9
+ image: <%= app_config.short_name %>-web:latest
10
+ build:
11
+ context: .
12
+ target: web
13
+ ports:
14
+ - "8080:80"
15
+ volumes:
16
+ . ./public:/app/public
17
+ depends_on:
18
+ - app
19
+ app:
20
+ image: <%= app_config.short_name %>-app:latest
21
+ build:
22
+ context: .
23
+ target: app
24
+ ports:
25
+ - "3000:3000"
26
+ volumes:
27
+ - <%= app_config.short_name %>:/app:nocopy
28
+ command: puma -C config/puma.rb
29
+ environment:
30
+ REDIS_URL: redis://redis
31
+ WEBPACKER_DEV_SERVER_HOST: webpacker
32
+ depends_on:
33
+ - db
34
+ - redis
35
+ webpacker:
36
+ image: <%= app_config.short_name %>-app:latest
37
+ ports:
38
+ - "3035:3035"
39
+ volumes:
40
+ - <%= app_config.short_name %>:/app:nocopy
41
+ command: bin/webpack-dev-server
42
+ environment:
43
+ WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
44
+ depends_on:
45
+ - app
46
+ worker:
47
+ image: <%= app_config.short_name %>-app:latest
48
+ volumes:
49
+ - <%= app_config.short_name %>:/app:nocopy
50
+ command: rails resque:work
51
+ environment:
52
+ REDIS_URL: redis://redis
53
+ QUEUE: '*'
54
+ depends_on:
55
+ - app
56
+ scheduler:
57
+ image: <%= app_config.short_name %>-app:latest
58
+ volumes:
59
+ - <%= app_config.short_name %>:/app:nocopy
60
+ command: rails resque:scheduler
61
+ environment:
62
+ REDIS_URL: redis://redis
63
+ depends_on:
64
+ - app
65
+ db:
66
+ image: postgres:9.6-alpine
67
+ volumes:
68
+ - ./tmp/db_data:/var/lib/postgresql/data
69
+ redis:
70
+ image: redis:5.0.5-alpine
71
+ mailcatcher:
72
+ image: schickling/mailcatcher
73
+ command: mailcatcher --no-quit --foreground --ip=0.0.0.0 -v
74
+ ports:
75
+ - "1080:1080"
@@ -0,0 +1,70 @@
1
+ data "aws_caller_identity" "current" {}
2
+
3
+ resource "aws_security_group" "ecs_tasks" {
4
+ name = "${var.name}-ecs-tasks"
5
+ description = "allow inbound access from the ALB only for ${var.name}"
6
+ vpc_id = var.vpc_id
7
+
8
+ ingress {
9
+ protocol = "tcp"
10
+ from_port = "80"
11
+ to_port = "80"
12
+ security_groups = [var.load_balance_security_group.id]
13
+ }
14
+
15
+ ingress {
16
+ protocol = "-1"
17
+ from_port = 0
18
+ to_port = 0
19
+ self = true
20
+ }
21
+
22
+ egress {
23
+ protocol = "-1"
24
+ from_port = 0
25
+ to_port = 0
26
+ cidr_blocks = ["0.0.0.0/0"]
27
+ }
28
+ }
29
+
30
+ resource "aws_ecs_cluster" "main" {
31
+ name = var.name
32
+ }
33
+
34
+ # Execution role for the cluster
35
+ data "template_file" "ecs_execution_role" {
36
+ template = file("${path.module}/policies/ecs_execution_role.json")
37
+
38
+ vars = {
39
+ aws_account_id = data.aws_caller_identity.current.account_id
40
+ }
41
+ }
42
+
43
+ resource "aws_iam_role" "ecs_execution_role" {
44
+ name = "${var.name}-ecs-execution-role"
45
+
46
+ assume_role_policy = data.template_file.ecs_execution_role.rendered
47
+ }
48
+
49
+ resource "aws_iam_role_policy" "ecs_execution_policy" {
50
+ name = "${var.name}-ecs-execution-policy"
51
+ role = aws_iam_role.ecs_execution_role.id
52
+ policy = file("${path.module}/policies/ecs_execution.json")
53
+ }
54
+
55
+ # Execution role for the task, this allows the docker image access to AWS resources
56
+ resource "aws_iam_role" "ecs_task_execution_role" {
57
+ name = "${var.name}-ecs-task-execution-role"
58
+
59
+ assume_role_policy = data.template_file.ecs_execution_role.rendered
60
+ }
61
+
62
+ data "template_file" "ecs_task_execution_policy" {
63
+ template = file("${path.module}/policies/ecs_task_execution.json")
64
+ }
65
+
66
+ resource "aws_iam_role_policy" "ecs_task_execution_policy" {
67
+ name = "${var.name}-ecs-task-execution-policy"
68
+ role = aws_iam_role.ecs_task_execution_role.id
69
+ policy = data.template_file.ecs_task_execution_policy.rendered
70
+ }
@@ -0,0 +1,48 @@
1
+ # ONE OFF
2
+ resource "aws_cloudwatch_log_group" "one_off" {
3
+ name = "/ecs/service/${var.name}-one-off"
4
+ retention_in_days = "14"
5
+ }
6
+
7
+ data "template_file" "one_off_task_definition" {
8
+ template = file("${path.module}/task_definitions/one_off.json")
9
+
10
+ vars = {
11
+ app_log_path = aws_cloudwatch_log_group.one_off.name
12
+ app_image = "${var.app_repository_url}:latest"
13
+ app_memory = var.app_process_memory
14
+ region = var.aws_region
15
+ app_memory = var.app_task_memory
16
+ environment = jsonencode(var.app_environment)
17
+ }
18
+ }
19
+
20
+ resource "aws_ecs_task_definition" "one_off" {
21
+ family = "${var.name}-one_off"
22
+ network_mode = "awsvpc"
23
+ requires_compatibilities = ["FARGATE"]
24
+ cpu = var.app_task_cpu
25
+ memory = var.app_task_memory
26
+ execution_role_arn = aws_iam_role.ecs_execution_role.arn
27
+ task_role_arn = aws_iam_role.ecs_task_execution_role.arn
28
+
29
+ container_definitions = data.template_file.one_off_task_definition.rendered
30
+ }
31
+
32
+ resource "aws_ecs_service" "one_off" {
33
+ name = "${var.name}-one_off"
34
+ cluster = aws_ecs_cluster.main.id
35
+ task_definition = aws_ecs_task_definition.one_off.arn
36
+ desired_count = "0"
37
+ launch_type = "FARGATE"
38
+
39
+ network_configuration {
40
+ security_groups = [aws_security_group.ecs_tasks.id]
41
+ subnets = var.task_subnets
42
+ }
43
+
44
+ lifecycle {
45
+ create_before_destroy = true
46
+ ignore_changes = [task_definition]
47
+ }
48
+ }
@@ -0,0 +1,19 @@
1
+ output "application_security_group" {
2
+ value = aws_security_group.ecs_tasks
3
+ }
4
+
5
+ output "web_service_name" {
6
+ value = aws_ecs_service.web.name
7
+ }
8
+
9
+ output "worker_service_name" {
10
+ value = aws_ecs_service.worker.name
11
+ }
12
+
13
+ output "ecs_cluster" {
14
+ value = aws_ecs_cluster.main
15
+ }
16
+
17
+ output "one_off_task_definition_name" {
18
+ value = aws_ecs_task_definition.one_off.family
19
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "Version": "2012-10-17",
3
+ "Statement": [
4
+ {
5
+ "Effect": "Allow",
6
+ "Action": [
7
+ "ecr:GetAuthorizationToken",
8
+ "ecr:BatchCheckLayerAvailability",
9
+ "ecr:GetDownloadUrlForLayer",
10
+ "ecr:BatchGetImage",
11
+ "logs:CreateLogStream",
12
+ "logs:PutLogEvents"
13
+ ],
14
+ "Resource": "*"
15
+ }
16
+ ]
17
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "Version": "2012-10-17",
3
+ "Statement": [
4
+ {
5
+ "Sid": "",
6
+ "Effect": "Allow",
7
+ "Principal": {
8
+ "Service": "ecs-tasks.amazonaws.com"
9
+ },
10
+ "Action": "sts:AssumeRole"
11
+ },
12
+ {
13
+ "Sid": "",
14
+ "Effect": "Allow",
15
+ "Principal": {
16
+ "AWS": "${aws_account_id}"
17
+ },
18
+ "Action": "sts:AssumeRole"
19
+ }
20
+ ]
21
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "Version": "2012-10-17",
3
+ "Statement": [
4
+ {
5
+ "Action": "iam:PassRole",
6
+ "Effect": "Allow",
7
+ "Resource": [
8
+ "*"
9
+ ],
10
+ "Condition": {
11
+ "StringLike": {
12
+ "iam:PassedToService": "ecs-tasks.amazonaws.com"
13
+ }
14
+ }
15
+ }
16
+ ]
17
+ }
@@ -0,0 +1,17 @@
1
+ resource "aws_security_group" "sshable" {
2
+ name = "sshable-${var.name}"
3
+ description = "Enable SSH to the world, please do not use unless you know what you are doing"
4
+ vpc_id = var.vpc_id
5
+
6
+ ingress {
7
+ from_port = 22
8
+ to_port = 22
9
+ protocol = "TCP"
10
+ cidr_blocks = ["0.0.0.0/0"]
11
+ }
12
+ }
13
+
14
+ resource "aws_key_pair" "sshable" {
15
+ key_name = var.name
16
+ public_key = var.key_pair_public_key
17
+ }
@@ -0,0 +1,18 @@
1
+ [
2
+ {
3
+ "image": "${app_image}",
4
+ "memory": ${app_memory},
5
+ "name": "one_off",
6
+ "networkMode": "awsvpc",
7
+ "essential": true,
8
+ "environment": ${environment},
9
+ "logConfiguration": {
10
+ "logDriver": "awslogs",
11
+ "options": {
12
+ "awslogs-group": "${app_log_path}",
13
+ "awslogs-region": "${region}",
14
+ "awslogs-stream-prefix": "ecs"
15
+ }
16
+ }
17
+ }
18
+ ]
@@ -0,0 +1,41 @@
1
+ [
2
+ {
3
+ "image": "${app_image}",
4
+ "memory": ${app_memory},
5
+ "name": "app",
6
+ "networkMode": "awsvpc",
7
+ "essential": true,
8
+ "command": [ "puma", "-C", "config/puma.rb" ],
9
+ "environment": ${environment},
10
+ "logConfiguration": {
11
+ "logDriver": "awslogs",
12
+ "options": {
13
+ "awslogs-group": "${app_log_path}",
14
+ "awslogs-region": "${region}",
15
+ "awslogs-stream-prefix": "ecs"
16
+ }
17
+ }
18
+ },
19
+ {
20
+ "image": "${web_image}",
21
+ "memory": 256,
22
+ "name": "web",
23
+ "networkMode": "awsvpc",
24
+ "essential": true,
25
+ "portMappings": [
26
+ {
27
+ "containerPort": 80,
28
+ "hostPort": 80,
29
+ "protocol": "tcp"
30
+ }
31
+ ],
32
+ "logConfiguration": {
33
+ "logDriver": "awslogs",
34
+ "options": {
35
+ "awslogs-group": "${web_log_path}",
36
+ "awslogs-region": "${region}",
37
+ "awslogs-stream-prefix": "ecs"
38
+ }
39
+ }
40
+ }
41
+ ]
@@ -0,0 +1,49 @@
1
+ [
2
+ {
3
+ "image": "${app_image}",
4
+ "memory": ${worker_app_memory},
5
+ "name": "worker",
6
+ "networkMode": "awsvpc",
7
+ "essential": true,
8
+ "command": [ "rails", "resque:work" ],
9
+ "environment": ${environment},
10
+ "healthCheck": {
11
+ "command": [ "CMD-SHELL", "ps -ef | grep \"resque\" | grep -v grep" ],
12
+ "interval": 5,
13
+ "timeout": 2,
14
+ "retries": 3,
15
+ "startPeriod": 30
16
+ },
17
+ "logConfiguration": {
18
+ "logDriver": "awslogs",
19
+ "options": {
20
+ "awslogs-group": "${app_log_path}",
21
+ "awslogs-region": "${region}",
22
+ "awslogs-stream-prefix": "ecs"
23
+ }
24
+ }
25
+ },
26
+ {
27
+ "image": "${app_image}",
28
+ "name": "scheduler",
29
+ "networkMode": "awsvpc",
30
+ "essential": true,
31
+ "command": [ "rails", "resque:scheduler" ],
32
+ "environment": ${environment},
33
+ "healthCheck": {
34
+ "command": [ "CMD-SHELL", "ps -ef | grep \"resque-scheduler\" | grep -v grep" ],
35
+ "interval": 5,
36
+ "timeout": 2,
37
+ "retries": 3,
38
+ "startPeriod": 30
39
+ },
40
+ "logConfiguration": {
41
+ "logDriver": "awslogs",
42
+ "options": {
43
+ "awslogs-group": "${app_log_path}",
44
+ "awslogs-region": "${region}",
45
+ "awslogs-stream-prefix": "ecs"
46
+ }
47
+ }
48
+ }
49
+ ]