ciinabox-ecs 0.2.9 → 0.2.10.alpha.1529494989
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +3 -1
- data/README.md +36 -11
- data/Rakefile +91 -25
- data/config/default_params.yml +10 -0
- data/lambdas/acm_issuer_validator/lib/install.sh +1 -1
- data/templates/ciinabox.rb +20 -10
- data/templates/ecs-cluster.rb +16 -0
- data/templates/ecs-services.rb +19 -26
- data/templates/lambdas.rb +1 -1
- data/templates/vpn.rb +280 -0
- metadata +38 -10
- data/lambdas/acm_issuer_validator/install.sh +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5925c9f4071982d31b38d632acbd0783cf6fa89417d2c5bc8dd46f3805bebdb1
|
4
|
+
data.tar.gz: c627c7dad29dea09241c7ea8b589b790a91d5a9850e6c8eaaa1514ec148cb731
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8211b47987f88749bf234d50233c27e4a5368c709379918f6d2a776f5229dc9efd252aa25a4b9bf94b70fe10bcb27f54f6aec48a7d08edc88c9a029db0ea0c4e
|
7
|
+
data.tar.gz: 86196ce321cef4b8cb5efa3b38d6c5a10b7298d4e2decc441215b5aae6d11cfe2c1857faac8d8acac65b5131c5a8e2e7e88b8a1d81968cec2731dd96ff04b715
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
[](https://travis-ci.com/base2services/ciinabox-ecs.svg?branch=develop)
|
2
|
+
|
1
3
|
# ciinabox ECS
|
2
4
|
|
3
5
|
ciinabox pronounced ciin a box is a set of automation for building
|
@@ -67,7 +69,7 @@ If you wish to add additional containers to your ciinabox environment, you can s
|
|
67
69
|
ciinaboxes/ciinabox_name/config/services.yml
|
68
70
|
|
69
71
|
e.g:
|
70
|
-
|
72
|
+
|
71
73
|
```yaml
|
72
74
|
services:
|
73
75
|
- jenkins:
|
@@ -80,7 +82,7 @@ e.g:
|
|
80
82
|
- artifactory:
|
81
83
|
- drone:
|
82
84
|
```
|
83
|
-
|
85
|
+
|
84
86
|
Please note that if you wish to do this, that you also need to create a CFNDSL template for the service under templates/services, with the name of the service as the filename (e.g. bitbucket.rb)
|
85
87
|
|
86
88
|
## Getting Started
|
@@ -91,10 +93,10 @@ To get started install `ciinabox-ecs` ruby gem
|
|
91
93
|
$ gem install ciinabox-ecs
|
92
94
|
```
|
93
95
|
|
94
|
-
During the setup process, you'll need to provide domain for the tools (e.g. `*.tools.example.com`) that has
|
96
|
+
During the setup process, you'll need to provide domain for the tools (e.g. `*.tools.example.com`) that has
|
95
97
|
matching Route53 zone in same AWS account where you are creating ciinabox. Optionally you can use local hosts file
|
96
98
|
hack in order to get routing working, but in this case usage of ACM certificates is not an option, and you'll need
|
97
|
-
to use selfsigned IAM server certificates.
|
99
|
+
to use selfsigned IAM server certificates.
|
98
100
|
|
99
101
|
### Quick setup
|
100
102
|
|
@@ -146,7 +148,7 @@ $ ciinabox-ecs full_install
|
|
146
148
|
|
147
149
|
5. Create ciinabox S3 source deployment bucket
|
148
150
|
```bash
|
149
|
-
$ ciinabox-ecs create_source_bucket [ciinabox_name]
|
151
|
+
$ ciinabox-ecs create_source_bucket [ciinabox_name]
|
150
152
|
Successfully created S3 source deployment bucket source.myciinabox.com
|
151
153
|
```
|
152
154
|
|
@@ -158,7 +160,7 @@ $ ciinabox-ecs full_install
|
|
158
160
|
|
159
161
|
7. Generate ciinabox cloudformation templates
|
160
162
|
```bash
|
161
|
-
$ ciinabox-ecs generate [ciinabox_name]
|
163
|
+
$ ciinabox-ecs generate [ciinabox_name]
|
162
164
|
Writing to output/ciinabox.json
|
163
165
|
using extras [[:yaml, "ciinaboxes/myciinabox/config/default_params.yml"], [:yaml, "config/services.yml"], [:ruby, "ext/helper.rb"]]
|
164
166
|
Loading YAML file ciinaboxes/myciinabox/config/default_params.yml
|
@@ -307,6 +309,16 @@ internal_elb: false
|
|
307
309
|
# needs internal_elb: true
|
308
310
|
```
|
309
311
|
|
312
|
+
## Nginx Reverse Proxy Config
|
313
|
+
|
314
|
+
If you need to pass in extra nginx configuration such as `client_max_body_size 100m;` to the proxy you can by adding the following text block to you params.yaml
|
315
|
+
|
316
|
+
```yaml
|
317
|
+
proxy_config: |
|
318
|
+
server_tokens off;
|
319
|
+
client_max_body_size 100m;
|
320
|
+
```
|
321
|
+
|
310
322
|
# Ciinabox configuration
|
311
323
|
|
312
324
|
## Bastion (Jumpbox) instance
|
@@ -348,6 +360,19 @@ bastionAMI:
|
|
348
360
|
|
349
361
|
```
|
350
362
|
|
363
|
+
## Vpn (OpenVpn) instance
|
364
|
+
|
365
|
+
You can create a openvpn access server instance complete by using the bellow config. It will create a new ecs cluster in the public subnet and launch [base2/openvpn-as](https://hub.docker.com/r/base2/openvpn-as/) container. It mounts a data volume to persist all configuration and logs in `/data`. Uses the existing `ecs_ami` as the underlying instance ami.
|
366
|
+
|
367
|
+
```yaml
|
368
|
+
include_vpn_stack: true
|
369
|
+
```
|
370
|
+
|
371
|
+
It is also possible to override the vpn instance type used for Launch Configuration. Defaults are below
|
372
|
+
|
373
|
+
```yaml
|
374
|
+
vpnInstanceType: t2.small
|
375
|
+
```
|
351
376
|
|
352
377
|
## IAM Roles
|
353
378
|
|
@@ -379,14 +404,14 @@ allow_nat_connections: false
|
|
379
404
|
|
380
405
|
## Automatic issuance and validation of ACM SSL certificate
|
381
406
|
|
382
|
-
This setting is enabled by default in default parameters. During the ciinabox init stage, you will be
|
383
|
-
asked if you want to utilise this functionality. Essentially, custom cloudformation resource based on
|
384
|
-
python [aws-acm-validator](https://pypi.python.org/pypi/aws-acm-cert-validator) python package will
|
385
|
-
request and validate ACM certificate through appropriate Route 53 DNS validation record.
|
407
|
+
This setting is enabled by default in default parameters. During the ciinabox init stage, you will be
|
408
|
+
asked if you want to utilise this functionality. Essentially, custom cloudformation resource based on
|
409
|
+
python [aws-acm-validator](https://pypi.python.org/pypi/aws-acm-cert-validator) python package will
|
410
|
+
request and validate ACM certificate through appropriate Route 53 DNS validation record.
|
386
411
|
|
387
412
|
### To disable during ciinabox setup
|
388
413
|
|
389
|
-
Answer question below with 'y' during ciinabox init stage
|
414
|
+
Answer question below with 'y' during ciinabox init stage
|
390
415
|
|
391
416
|
```text
|
392
417
|
Use selfsigned rather than ACM issued and validated certificate (y/n)? [n]
|
data/Rakefile
CHANGED
@@ -11,6 +11,8 @@ require 'tempfile'
|
|
11
11
|
require 'json'
|
12
12
|
require_relative './ext/common_helper'
|
13
13
|
require_relative './ext/zip_helper'
|
14
|
+
require 'aws-sdk-s3'
|
15
|
+
require 'aws-sdk-cloudformation'
|
14
16
|
require 'ciinabox-ecs' if Gem::Specification::find_all_by_name('ciinabox-ecs').any?
|
15
17
|
|
16
18
|
namespace :ciinabox do
|
@@ -38,7 +40,7 @@ namespace :ciinabox do
|
|
38
40
|
config = default_params
|
39
41
|
end
|
40
42
|
|
41
|
-
Dir["#{ciinaboxes_dir}/#{ciinabox_name}/config/*.yml"].each {
|
43
|
+
Dir["#{ciinaboxes_dir}/#{ciinabox_name}/config/*.yml"].each {|config_file|
|
42
44
|
if not config_file.include?('params.yml')
|
43
45
|
config = config.merge(YAML.load(File.read(config_file)))
|
44
46
|
end
|
@@ -48,12 +50,12 @@ namespace :ciinabox do
|
|
48
50
|
|
49
51
|
# ciinabox binary version
|
50
52
|
if Gem.loaded_specs['ciinabox-ecs'].nil?
|
51
|
-
config['ciinabox_binary_version'] = `git rev-parse --short HEAD`.gsub("\n",'')
|
53
|
+
config['ciinabox_binary_version'] = `git rev-parse --short HEAD`.gsub("\n", '')
|
52
54
|
else
|
53
55
|
config['ciinabox_binary_version'] = Gem.loaded_specs['ciinabox-ecs'].version.to_s
|
54
56
|
end
|
55
57
|
|
56
|
-
File.write('debug-ciinabox.config.yaml',config.to_yaml) if ENV['DEBUG']
|
58
|
+
File.write('debug-ciinabox.config.yaml', config.to_yaml) if ENV['DEBUG']
|
57
59
|
|
58
60
|
stack_name = config["stack_name"] || "ciinabox"
|
59
61
|
|
@@ -64,8 +66,8 @@ namespace :ciinabox do
|
|
64
66
|
templates2 = Dir["#{ciinaboxes_dir}/#{ciinabox_name}/templates/**/*.rb"]
|
65
67
|
|
66
68
|
## we want to exclude overridden templates
|
67
|
-
templatesLocalFileNames = templates2.collect {
|
68
|
-
templates = templates.select {
|
69
|
+
templatesLocalFileNames = templates2.collect {|templateFile| File.basename(templateFile)}
|
70
|
+
templates = templates.select {|templateFile| not templatesLocalFileNames.include? File.basename(templateFile)}
|
69
71
|
templates = templates + templates2
|
70
72
|
end
|
71
73
|
|
@@ -87,13 +89,13 @@ namespace :ciinabox do
|
|
87
89
|
tmp_file = write_config_tmp_file(config)
|
88
90
|
|
89
91
|
CfnDsl::RakeTask.new do |t|
|
90
|
-
extras = [[:yaml,"#{current_dir}/config/default_params.yml"]]
|
92
|
+
extras = [[:yaml, "#{current_dir}/config/default_params.yml"]]
|
91
93
|
extras << [:yaml, "#{current_dir}/config/default_lambdas.yml"]
|
92
94
|
if File.exist? "#{ciinaboxes_dir}/ciinabox_config.yml"
|
93
95
|
extras << [:yaml, "#{ciinaboxes_dir}/ciinabox_config.yml"]
|
94
96
|
end
|
95
|
-
(Dir["#{ciinaboxes_dir}/#{ciinabox_name}/config/*.yml"].map {
|
96
|
-
extras << [:ruby,"#{current_dir}/ext/helper.rb"]
|
97
|
+
(Dir["#{ciinaboxes_dir}/#{ciinabox_name}/config/*.yml"].map {|f| [:yaml, f]}).each {|c| extras << c}
|
98
|
+
extras << [:ruby, "#{current_dir}/ext/helper.rb"]
|
97
99
|
extras << [:yaml, tmp_file.path]
|
98
100
|
t.cfndsl_opts = {
|
99
101
|
verbose: true,
|
@@ -165,16 +167,16 @@ namespace :ciinabox do
|
|
165
167
|
if File.exist?("#{ciinaboxes_dir}/#{ciinabox_name}/config/params.yml")
|
166
168
|
config_output = user_params.merge(input_hash) #Merges input hash into user-provided template
|
167
169
|
config_yaml = config_output.to_yaml #Convert output to YAML for writing
|
168
|
-
File.open("#{ciinaboxes_dir}/#{ciinabox_name}/config/params.yml", 'w') {
|
170
|
+
File.open("#{ciinaboxes_dir}/#{ciinabox_name}/config/params.yml", 'w') {|f| f.write(config_yaml)}
|
169
171
|
else
|
170
|
-
File.open("#{ciinaboxes_dir}/#{ciinabox_name}/config/params.yml", 'w') {
|
172
|
+
File.open("#{ciinaboxes_dir}/#{ciinabox_name}/config/params.yml", 'w') {|f| f.write(input_result)}
|
171
173
|
end
|
172
174
|
|
173
175
|
default_services = YAML.load(File.read("#{current_dir}/config/default_services.yml"))
|
174
176
|
|
175
177
|
class ::Hash
|
176
178
|
def deep_merge(second)
|
177
|
-
merger = proc {
|
179
|
+
merger = proc {|key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2}
|
178
180
|
self.merge(second.to_h, &merger)
|
179
181
|
end
|
180
182
|
end
|
@@ -184,10 +186,10 @@ namespace :ciinabox do
|
|
184
186
|
user_services = YAML.load(File.read("#{ciinaboxes_dir}/#{ciinabox_name}/config/services.yml"))
|
185
187
|
combined_services = default_services.deep_merge(user_services)
|
186
188
|
yml_combined_services = combined_services.to_yaml
|
187
|
-
File.open("#{ciinaboxes_dir}/#{ciinabox_name}/config/services.yml", 'w') {
|
189
|
+
File.open("#{ciinaboxes_dir}/#{ciinabox_name}/config/services.yml", 'w') {|f| f.write(yml_combined_services)}
|
188
190
|
else
|
189
191
|
yml_default_services = default_services.to_yaml
|
190
|
-
File.open("#{ciinaboxes_dir}/#{ciinabox_name}/config/services.yml", 'w') {
|
192
|
+
File.open("#{ciinaboxes_dir}/#{ciinabox_name}/config/services.yml", 'w') {|f| f.write(yml_default_services)}
|
191
193
|
end
|
192
194
|
|
193
195
|
display_active_ciinabox ciinaboxes_dir, ciinabox_name
|
@@ -251,13 +253,12 @@ namespace :ciinabox do
|
|
251
253
|
check_active_ciinabox(config)
|
252
254
|
ciinabox_name = config['ciinabox_name']
|
253
255
|
cert_dir = "#{ciinaboxes_dir}/#{ciinabox_name}"
|
254
|
-
status, result = aws_execute(
|
256
|
+
status, result = aws_execute(config, [
|
255
257
|
'iam', 'upload-server-certificate',
|
256
258
|
'--server-certificate-name ciinabox',
|
257
259
|
"--certificate-body file://#{cert_dir}/ssl/ciinabox.crt",
|
258
260
|
"--private-key file://#{cert_dir}/ssl/ciinabox.key",
|
259
|
-
"--certificate-chain file://#{cert_dir}/ssl/ciinabox.crt"
|
260
|
-
'--output json'
|
261
|
+
"--certificate-chain file://#{cert_dir}/ssl/ciinabox.crt"
|
261
262
|
])
|
262
263
|
if status != 0
|
263
264
|
puts "fail to create or update IAM server-certificates. See error logs for details"
|
@@ -388,6 +389,13 @@ namespace :ciinabox do
|
|
388
389
|
desc('Package Lambda Functions as ZipFiles')
|
389
390
|
task :package_lambdas do
|
390
391
|
check_active_ciinabox(config)
|
392
|
+
|
393
|
+
# custom lambda modification
|
394
|
+
lambda_stack_required = config['acm_auto_issue_validate']
|
395
|
+
# in future any new conditions for lambda stack would be added here
|
396
|
+
# lambda_stack_required ||= some_new_condition
|
397
|
+
config['lambdas'] = nil unless lambda_stack_required
|
398
|
+
|
391
399
|
if !config['lambdas'].nil? && !config['lambdas']['functions'].nil?
|
392
400
|
log_header 'Package lambda functions'
|
393
401
|
|
@@ -514,7 +522,7 @@ namespace :ciinabox do
|
|
514
522
|
'--out json'
|
515
523
|
])
|
516
524
|
resp = JSON.parse(result)
|
517
|
-
cert_output = resp['Stacks'][0]['Outputs'].find {
|
525
|
+
cert_output = resp['Stacks'][0]['Outputs'].find {|k| k['OutputKey'] == 'DefaultSSLCertificate'}
|
518
526
|
if cert_output.nil?
|
519
527
|
STDERR.puts("ACM certificate is not present in stack outputs")
|
520
528
|
exit -1
|
@@ -526,6 +534,64 @@ namespace :ciinabox do
|
|
526
534
|
puts "Set #{cert_arn} as default_cert_arn"
|
527
535
|
end
|
528
536
|
|
537
|
+
|
538
|
+
desc('validate cloudformation templates')
|
539
|
+
task :validate do
|
540
|
+
cfn = Aws::CloudFormation::Client.new(region: config['source_region'])
|
541
|
+
s3 = Aws::S3::Client.new(region: config['source_region'])
|
542
|
+
Dir.glob("output/**/*.json") do |file|
|
543
|
+
template_content = IO.read(file)
|
544
|
+
# Skip if empty template generated
|
545
|
+
next if (template_content == "null\n")
|
546
|
+
template = File.open(file, 'rb')
|
547
|
+
filename = File.basename file
|
548
|
+
template_bytesize = template_content.bytesize
|
549
|
+
file_size = File.size file
|
550
|
+
local_validation = (template_content.bytesize < 51200)
|
551
|
+
puts "INFO - #{file}: Filesize: #{file_size}, Bytesize: #{template_bytesize}, local validation: #{local_validation}"
|
552
|
+
begin
|
553
|
+
if not local_validation
|
554
|
+
puts "INFO - Copy #{file} -> s3://#{config['source_bucket']}/cloudformation/#{project_name}/validate/#{filename}"
|
555
|
+
s3.put_object({
|
556
|
+
body: template,
|
557
|
+
bucket: "#{config['source_bucket']}",
|
558
|
+
key: "cloudformation/#{project_name}/validate/#{filename}",
|
559
|
+
})
|
560
|
+
template_url = "https://#{config['source_bucket']}.s3.amazonaws.com/cloudformation/#{project_name}/validate/#{filename}"
|
561
|
+
puts "INFO - Copied #{file} to s3://#{config['source_bucket']}/cloudformation/#{project_name}/validate/#{filename}"
|
562
|
+
puts "INFO - Validating #{template_url}"
|
563
|
+
else
|
564
|
+
puts "INFO - Validating #{file}"
|
565
|
+
end
|
566
|
+
begin
|
567
|
+
resp = cfn.validate_template({ template_url: template_url }) unless local_validation
|
568
|
+
resp = cfn.validate_template({ template_body: template_content }) if local_validation
|
569
|
+
puts "INFO - Template #{filename} validated successfully"
|
570
|
+
rescue => e
|
571
|
+
puts "ERROR - Template #{filename} failed to validate: #{e}"
|
572
|
+
exit 1
|
573
|
+
end
|
574
|
+
|
575
|
+
rescue => e
|
576
|
+
puts "ERROR - #{e.class}, #{e}"
|
577
|
+
exit 1
|
578
|
+
end
|
579
|
+
end
|
580
|
+
puts "INFO - #{Dir["output/**/*.json"].count} templates validated successfully"
|
581
|
+
end
|
582
|
+
|
583
|
+
desc('vendor templates from ciinabox gem into ciinabox folder')
|
584
|
+
task :vendor do
|
585
|
+
Dir["#{current_dir}/templates/**/*.rb"].each do |template_path|
|
586
|
+
relative_path = template_path.gsub("#{current_dir}/", '')
|
587
|
+
target_path = "#{@ciinaboxes_dir}/#{@ciinabox_name}/#{relative_path}"
|
588
|
+
target_dir = File.dirname(target_path)
|
589
|
+
FileUtils.mkdir_p target_dir
|
590
|
+
puts "#{relative_path} -> #{target_path}"
|
591
|
+
FileUtils.copy template_path, target_path
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
529
595
|
def add_ciinabox_config_setting(element, value)
|
530
596
|
file_name = "#{@ciinaboxes_dir}/#{@ciinabox_name}/config/params.yml"
|
531
597
|
File.write(file_name,
|
@@ -535,7 +601,7 @@ namespace :ciinabox do
|
|
535
601
|
)
|
536
602
|
end
|
537
603
|
|
538
|
-
def remove_update_ciinabox_config_setting(element, new_value='')
|
604
|
+
def remove_update_ciinabox_config_setting(element, new_value = '')
|
539
605
|
f = File.new("#{@ciinaboxes_dir}/#{@ciinabox_name}/config/params.yml", 'r+')
|
540
606
|
found = false
|
541
607
|
f.each do |line|
|
@@ -551,7 +617,7 @@ namespace :ciinabox do
|
|
551
617
|
end
|
552
618
|
end
|
553
619
|
f.close
|
554
|
-
add_ciinabox_config_setting(element, new_value) if((not found) and (not new_value.empty?))
|
620
|
+
add_ciinabox_config_setting(element, new_value) if ((not found) and (not new_value.empty?))
|
555
621
|
end
|
556
622
|
|
557
623
|
def check_active_ciinabox(config)
|
@@ -609,12 +675,12 @@ namespace :ciinabox do
|
|
609
675
|
question = ("#{question} (y/n)? [#{default ? 'y' : 'n'}]")
|
610
676
|
while true
|
611
677
|
case get_input(question)
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
678
|
+
when ''
|
679
|
+
return default
|
680
|
+
when 'Y', 'y', 'yes'
|
681
|
+
return true
|
682
|
+
when /\A[nN]o?\Z/ #n or no
|
683
|
+
return false
|
618
684
|
end
|
619
685
|
end
|
620
686
|
end
|
data/config/default_params.yml
CHANGED
@@ -287,6 +287,7 @@ ecs_iam_role_permissions_default:
|
|
287
287
|
# CertName: x
|
288
288
|
# StackOctetA: 11
|
289
289
|
# StackOctetB: 12
|
290
|
+
vpnInstanceType: t2.small
|
290
291
|
bastionInstanceType: t2.micro
|
291
292
|
bastionAMI:
|
292
293
|
us-east-1:
|
@@ -309,3 +310,12 @@ bastionAMI:
|
|
309
310
|
ami: ami-c7ee5ca8
|
310
311
|
|
311
312
|
acm_auto_issue_validate: true
|
313
|
+
|
314
|
+
# Enbale open VPN
|
315
|
+
include_vpn_stack: false
|
316
|
+
# open the vpn upd connection port 1194 to all ips
|
317
|
+
vpn_udp_public: false
|
318
|
+
|
319
|
+
# Default public access is considered whole internet
|
320
|
+
publicAccess:
|
321
|
+
- 0.0.0.0/0
|
@@ -16,5 +16,5 @@ function pipinstall () {
|
|
16
16
|
if [ $(which docker) == '' ]; then
|
17
17
|
pipinstall
|
18
18
|
else
|
19
|
-
docker run --rm -v $DIR/..:/dst -w /dst -u
|
19
|
+
docker run --rm -v $DIR/..:/dst -w /dst -u $UID python:3-alpine pip install aws-acm-cert-validator==0.1.11 -t lib
|
20
20
|
fi
|
data/templates/ciinabox.rb
CHANGED
@@ -35,11 +35,7 @@ CloudFormation do
|
|
35
35
|
}
|
36
36
|
|
37
37
|
# ECS Services Stack
|
38
|
-
|
39
|
-
Type 'AWS::CloudFormation::Stack'
|
40
|
-
Property('TemplateURL', "https://#{source_bucket}.s3.amazonaws.com/ciinabox/#{ciinabox_version}/ecs-services.json")
|
41
|
-
Property('TimeoutInMinutes', 15)
|
42
|
-
Property('Parameters',{
|
38
|
+
services_params = {
|
43
39
|
ECSCluster: Ref(cluster_name),
|
44
40
|
VPC: FnGetAtt('VPCStack', 'Outputs.VPCId'),
|
45
41
|
SubnetPublicA: FnGetAtt('VPCStack', 'Outputs.SubnetPublicA'),
|
@@ -51,8 +47,14 @@ CloudFormation do
|
|
51
47
|
SecurityGroupOps: FnGetAtt('VPCStack', 'Outputs.SecurityGroupOps'),
|
52
48
|
SecurityGroupDev: FnGetAtt('VPCStack', 'Outputs.SecurityGroupDev'),
|
53
49
|
SecurityGroupNatGateway: FnGetAtt('VPCStack', 'Outputs.SecurityGroupNatGateway'),
|
54
|
-
|
55
|
-
|
50
|
+
}
|
51
|
+
services_params[:CRAcmCertArn] = FnGetAtt('LambdasStack','Outputs.LambdaCRIssueACMCertificateArn') if acm_auto_issue_validate
|
52
|
+
|
53
|
+
Resource('ECSServicesStack') {
|
54
|
+
Type 'AWS::CloudFormation::Stack'
|
55
|
+
Property('TemplateURL', "https://#{source_bucket}.s3.amazonaws.com/ciinabox/#{ciinabox_version}/ecs-services.json")
|
56
|
+
Property('TimeoutInMinutes', 15)
|
57
|
+
Property('Parameters',services_params)
|
56
58
|
}
|
57
59
|
|
58
60
|
#These are the commona params for use below in "foreign templates
|
@@ -70,12 +72,15 @@ CloudFormation do
|
|
70
72
|
base_params.merge!("RouteTablePrivate#{az}" => FnGetAtt('VPCStack', "Outputs.RouteTablePrivate#{az}"))
|
71
73
|
end
|
72
74
|
|
73
|
-
|
75
|
+
lambda_stack_required = acm_auto_issue_validate
|
76
|
+
# in future any new conditions for lambda stack would be added here
|
77
|
+
# lambda_stack_required ||= some_new_condition
|
78
|
+
# in future any new conditions for lambda stack would be added here
|
74
79
|
Resource('LambdasStack') do
|
75
80
|
Type 'AWS::CloudFormation::Stack'
|
76
81
|
Property('TemplateURL', "https://#{source_bucket}.s3.amazonaws.com/ciinabox/#{ciinabox_version}/lambdas.json")
|
77
82
|
Property('Parameters', base_params)
|
78
|
-
end
|
83
|
+
end if lambda_stack_required
|
79
84
|
|
80
85
|
|
81
86
|
# Bastion if required
|
@@ -85,7 +90,12 @@ CloudFormation do
|
|
85
90
|
Property('Parameters', base_params)
|
86
91
|
end if include_bastion_stack
|
87
92
|
|
88
|
-
|
93
|
+
# Vpn if required
|
94
|
+
Resource('VpnStack') do
|
95
|
+
Type 'AWS::CloudFormation::Stack'
|
96
|
+
Property('TemplateURL', "https://#{source_bucket}.s3.amazonaws.com/ciinabox/#{ciinabox_version}/vpn.json")
|
97
|
+
Property('Parameters', base_params)
|
98
|
+
end if include_vpn_stack
|
89
99
|
|
90
100
|
#Foreign templates
|
91
101
|
#e.g CIINABOXES_DIR/CIINABOX/templates/x.rb
|
data/templates/ecs-cluster.rb
CHANGED
@@ -162,6 +162,22 @@ CloudFormation {
|
|
162
162
|
if not ecs_block_device_mapping.empty?
|
163
163
|
Property("BlockDeviceMappings", ecs_block_device_mapping)
|
164
164
|
end
|
165
|
+
if defined? proxy_config
|
166
|
+
Metadata(
|
167
|
+
'AWS::CloudFormation::Init': {
|
168
|
+
config: {
|
169
|
+
files: {
|
170
|
+
'/opt/proxy/proxy_config.conf': {
|
171
|
+
content: proxy_config,
|
172
|
+
mode: "000644",
|
173
|
+
owner: "root",
|
174
|
+
group: "root"
|
175
|
+
}
|
176
|
+
}
|
177
|
+
}
|
178
|
+
}
|
179
|
+
)
|
180
|
+
end
|
165
181
|
UserData FnBase64(FnJoin("", [
|
166
182
|
"#!/bin/bash\n",
|
167
183
|
"echo ECS_CLUSTER=", Ref('ECSCluster'), " >> /etc/ecs/ecs.config\n",
|
data/templates/ecs-services.rb
CHANGED
@@ -261,6 +261,23 @@ CloudFormation {
|
|
261
261
|
end
|
262
262
|
end
|
263
263
|
|
264
|
+
volumes = []
|
265
|
+
mount_points = []
|
266
|
+
|
267
|
+
# Timezone
|
268
|
+
volumes << { Name: 'timezone', Host: { SourcePath: '/etc/localtime' }}
|
269
|
+
mount_points << { ContainerPath: '/etc/localtime', SourceVolume: 'timezone', ReadOnly: true }
|
270
|
+
|
271
|
+
# Docker Socket
|
272
|
+
volumes << { Name: 'docker_sock', Host: { SourcePath: '/var/run/docker.sock' }}
|
273
|
+
mount_points << { ContainerPath: '/tmp/docker.sock', SourceVolume: 'docker_sock', ReadOnly: false }
|
274
|
+
|
275
|
+
# Proxy Config
|
276
|
+
if defined? proxy_config
|
277
|
+
volumes << { Name: 'proxy_config', Host: { SourcePath: '/opt/proxy/proxy_config.conf' }}
|
278
|
+
mount_points << { ContainerPath: '/etc/nginx/conf.d/proxy_config.conf', SourceVolume: 'proxy_config', ReadOnly: true }
|
279
|
+
end
|
280
|
+
|
264
281
|
Resource('ProxyTask') {
|
265
282
|
Type "AWS::ECS::TaskDefinition"
|
266
283
|
Property('ContainerDefinitions', [
|
@@ -274,34 +291,10 @@ CloudFormation {
|
|
274
291
|
ContainerPort: 80
|
275
292
|
}],
|
276
293
|
Essential: true,
|
277
|
-
MountPoints:
|
278
|
-
{
|
279
|
-
ContainerPath: '/etc/localtime',
|
280
|
-
SourceVolume: 'timezone',
|
281
|
-
ReadOnly: true
|
282
|
-
},
|
283
|
-
{
|
284
|
-
ContainerPath: '/tmp/docker.sock',
|
285
|
-
SourceVolume: 'docker_sock',
|
286
|
-
ReadOnly: false
|
287
|
-
}
|
288
|
-
]
|
289
|
-
}
|
290
|
-
])
|
291
|
-
Property('Volumes', [
|
292
|
-
{
|
293
|
-
Name: 'timezone',
|
294
|
-
Host: {
|
295
|
-
SourcePath: '/etc/localtime'
|
296
|
-
}
|
297
|
-
},
|
298
|
-
{
|
299
|
-
Name: 'docker_sock',
|
300
|
-
Host: {
|
301
|
-
SourcePath: '/var/run/docker.sock'
|
302
|
-
}
|
294
|
+
MountPoints: mount_points
|
303
295
|
}
|
304
296
|
])
|
297
|
+
Property('Volumes', volumes)
|
305
298
|
}
|
306
299
|
|
307
300
|
Resource('ProxyService') {
|
data/templates/lambdas.rb
CHANGED
data/templates/vpn.rb
ADDED
@@ -0,0 +1,280 @@
|
|
1
|
+
CloudFormation do
|
2
|
+
|
3
|
+
# Template metadata
|
4
|
+
AWSTemplateFormatVersion '2010-09-09'
|
5
|
+
Description "ciinabox - Vpn v#{ciinabox_version}"
|
6
|
+
|
7
|
+
# Parameters
|
8
|
+
Parameter('EnvironmentType'){ Type 'String' }
|
9
|
+
Parameter('EnvironmentName'){ Type 'String' }
|
10
|
+
Parameter('VPC'){ Type 'String' }
|
11
|
+
Parameter('RouteTablePrivateA'){ Type 'String' }
|
12
|
+
Parameter('RouteTablePrivateB'){ Type 'String' }
|
13
|
+
Parameter('SubnetPublicA'){ Type 'String' }
|
14
|
+
Parameter('SubnetPublicB'){ Type 'String' }
|
15
|
+
Parameter('SecurityGroupBackplane'){ Type 'String' }
|
16
|
+
Parameter('SecurityGroupOps'){ Type 'String' }
|
17
|
+
Parameter('SecurityGroupDev'){ Type 'String' }
|
18
|
+
|
19
|
+
# Global mappings
|
20
|
+
Mapping('EnvironmentType', Mappings['EnvironmentType'])
|
21
|
+
Mapping('ecsAMI', ecs_ami)
|
22
|
+
|
23
|
+
security_groups = []
|
24
|
+
|
25
|
+
rules = []
|
26
|
+
opsAccess.each do |ip|
|
27
|
+
rules << { IpProtocol: 'tcp', FromPort: '22', ToPort: '22', CidrIp: ip }
|
28
|
+
rules << { IpProtocol: 'tcp', FromPort: '443', ToPort: '443', CidrIp: ip }
|
29
|
+
rules << { IpProtocol: 'tcp', FromPort: '9443', ToPort: '9443', CidrIp: ip }
|
30
|
+
rules << { IpProtocol: 'tcp', FromPort: '943', ToPort: '943', CidrIp: ip }
|
31
|
+
rules << { IpProtocol: 'udp', FromPort: '1194', ToPort: '1194', CidrIp: ip }
|
32
|
+
end
|
33
|
+
|
34
|
+
Resource("VpnSecurityGroupOps") {
|
35
|
+
Type 'AWS::EC2::SecurityGroup'
|
36
|
+
Property('VpcId', Ref('VPC'))
|
37
|
+
Property('GroupDescription', 'Ops External Access')
|
38
|
+
Property('SecurityGroupIngress', rules)
|
39
|
+
}
|
40
|
+
|
41
|
+
security_groups << Ref('VpnSecurityGroupOps')
|
42
|
+
|
43
|
+
rules = []
|
44
|
+
devAccess.each do |ip|
|
45
|
+
rules << { IpProtocol: 'tcp', FromPort: '443', ToPort: '443', CidrIp: ip }
|
46
|
+
rules << { IpProtocol: 'tcp', FromPort: '9443', ToPort: '9443', CidrIp: ip }
|
47
|
+
rules << { IpProtocol: 'tcp', FromPort: '943', ToPort: '943', CidrIp: ip }
|
48
|
+
rules << { IpProtocol: 'udp', FromPort: '1194', ToPort: '1194', CidrIp: ip }
|
49
|
+
end
|
50
|
+
|
51
|
+
Resource("VpnSecurityGroupDev") {
|
52
|
+
Type 'AWS::EC2::SecurityGroup'
|
53
|
+
Property('VpcId', Ref('VPC'))
|
54
|
+
Property('GroupDescription', 'Dev Team Access')
|
55
|
+
Property('SecurityGroupIngress', rules)
|
56
|
+
}
|
57
|
+
|
58
|
+
security_groups << Ref('VpnSecurityGroupDev')
|
59
|
+
|
60
|
+
if vpn_udp_public
|
61
|
+
|
62
|
+
rules = []
|
63
|
+
publicAccess.each do |ip|
|
64
|
+
rules << { IpProtocol: 'udp', FromPort: '1194', ToPort: '1194', CidrIp: ip }
|
65
|
+
end
|
66
|
+
|
67
|
+
Resource("VpnSecurityGroupPublic") {
|
68
|
+
Type 'AWS::EC2::SecurityGroup'
|
69
|
+
Property('VpcId', Ref('VPC'))
|
70
|
+
Property('GroupDescription', 'VPN Access')
|
71
|
+
Property('SecurityGroupIngress', rules)
|
72
|
+
}
|
73
|
+
|
74
|
+
security_groups << Ref('VpnSecurityGroupPublic')
|
75
|
+
end
|
76
|
+
|
77
|
+
IAM_Role("Role") {
|
78
|
+
AssumeRolePolicyDocument({
|
79
|
+
Statement: [
|
80
|
+
Effect: 'Allow',
|
81
|
+
Principal: { Service: [ 'ec2.amazonaws.com' ] },
|
82
|
+
Action: [ 'sts:AssumeRole' ]
|
83
|
+
]
|
84
|
+
})
|
85
|
+
Path '/'
|
86
|
+
Policies([
|
87
|
+
{
|
88
|
+
PolicyName: 'read-only',
|
89
|
+
PolicyDocument: {
|
90
|
+
Statement: [
|
91
|
+
{
|
92
|
+
Effect: 'Allow',
|
93
|
+
Action: [ 'autoscaling:Describe*', 'ec2:Describe*', 's3:Get*', 's3:List*'],
|
94
|
+
Resource: '*'
|
95
|
+
}
|
96
|
+
]
|
97
|
+
}
|
98
|
+
},
|
99
|
+
{
|
100
|
+
PolicyName: 'attach-ec2-volumes',
|
101
|
+
PolicyDocument: {
|
102
|
+
Statement: [
|
103
|
+
{
|
104
|
+
Effect: 'Allow',
|
105
|
+
Action: [ 'ec2:AttachVolume','ec2:CreateVolume', 'ec2:Describe*', 'ec2:DetachVolume' ],
|
106
|
+
Resource: '*'
|
107
|
+
}
|
108
|
+
]
|
109
|
+
}
|
110
|
+
},
|
111
|
+
{
|
112
|
+
PolicyName: 'AttachNetworkInterface',
|
113
|
+
PolicyDocument: {
|
114
|
+
Statement: [
|
115
|
+
{
|
116
|
+
Effect: 'Allow',
|
117
|
+
Action: [ 'ec2:DescribeNetworkInterfaces', 'ec2:AttachNetworkInterface','ec2:AssociateAddress' ],
|
118
|
+
Resource: '*'
|
119
|
+
}
|
120
|
+
]
|
121
|
+
}
|
122
|
+
},
|
123
|
+
{
|
124
|
+
PolicyName: 'ECSServiceRole',
|
125
|
+
PolicyDocument: {
|
126
|
+
Statement: [
|
127
|
+
{
|
128
|
+
Effect: 'Allow',
|
129
|
+
Action: [
|
130
|
+
'ecs:CreateCluster',
|
131
|
+
'ecs:DeregisterContainerInstance',
|
132
|
+
'ecs:DiscoverPollEndpoint',
|
133
|
+
'ecs:Poll',
|
134
|
+
'ecs:RegisterContainerInstance',
|
135
|
+
'ecs:StartTelemetrySession',
|
136
|
+
'ecs:Submit*',
|
137
|
+
'ec2:AuthorizeSecurityGroupIngress'
|
138
|
+
],
|
139
|
+
Resource: '*'
|
140
|
+
}
|
141
|
+
]
|
142
|
+
}
|
143
|
+
}
|
144
|
+
])
|
145
|
+
}
|
146
|
+
|
147
|
+
ECS_Cluster('CiinaboxVpn')
|
148
|
+
|
149
|
+
InstanceProfile('InstanceProfile') {
|
150
|
+
Path '/'
|
151
|
+
Roles [ Ref('Role') ]
|
152
|
+
}
|
153
|
+
|
154
|
+
EC2_EIP('VpnIPAddress') {
|
155
|
+
Domain 'vpc'
|
156
|
+
}
|
157
|
+
|
158
|
+
EC2_Volume("VpnVolume") {
|
159
|
+
DeletionPolicy 'Snapshot'
|
160
|
+
Size '10'
|
161
|
+
VolumeType 'gp2'
|
162
|
+
if defined? vpn_data_volume_snapshot
|
163
|
+
SnapshotId vpn_data_volume_snapshot
|
164
|
+
end
|
165
|
+
AvailabilityZone FnSelect(0, FnGetAZs(""))
|
166
|
+
addTag('Name', 'ciinabox-vpn-config-xx')
|
167
|
+
addTag('Environment', 'ciinabox')
|
168
|
+
addTag('EnvironmentType', 'ciinabox')
|
169
|
+
addTag('shelvery:create_backup','true')
|
170
|
+
addTag('shelvery:config:shelvery_keep_daily_backups', '7')
|
171
|
+
addTag('shelvery:config:shelvery_keep_weekly_backups', '4')
|
172
|
+
addTag('shelvery:config:shelvery_keep_monthly_backups', '12')
|
173
|
+
}
|
174
|
+
|
175
|
+
AutoScaling_LaunchConfiguration('LaunchConfig') {
|
176
|
+
DependsOn ['VpnIPAddress']
|
177
|
+
ImageId FnFindInMap('ecsAMI', Ref('AWS::Region'), 'ami')
|
178
|
+
KeyName FnFindInMap('EnvironmentType', 'ciinabox', 'KeyName')
|
179
|
+
AssociatePublicIpAddress true
|
180
|
+
IamInstanceProfile Ref('InstanceProfile')
|
181
|
+
SecurityGroups security_groups
|
182
|
+
Property('InstanceType', vpnInstanceType)
|
183
|
+
UserData FnBase64(FnJoin('',[
|
184
|
+
"#!/bin/bash\n",
|
185
|
+
"echo ECS_CLUSTER=", Ref('CiinaboxVpn'), " >> /etc/ecs/ecs.config\n",
|
186
|
+
"INSTANCE_ID=$(echo `/opt/aws/bin/ec2-metadata -i | cut -f2 -d:`)\n",
|
187
|
+
'export NEW_HOSTNAME=', Ref('EnvironmentName'),"-vpn-xx-`/opt/aws/bin/ec2-metadata --instance-id|/usr/bin/awk '{print $2}'`", "\n",
|
188
|
+
"echo \"NEW_HOSTNAME=$NEW_HOSTNAME\" \n",
|
189
|
+
"hostname $NEW_HOSTNAME\n",
|
190
|
+
"sed -i \"s/^HOSTNAME=.*/HOSTNAME=$NEW_HOSTNAME/\" /etc/sysconfig/network\n",
|
191
|
+
"stop ecs\n",
|
192
|
+
"service docker stop\n",
|
193
|
+
"aws --region ", Ref("AWS::Region"), " ec2 attach-volume --volume-id ", Ref('VpnVolume'), " --instance-id ${INSTANCE_ID} --device /dev/sdb\n",
|
194
|
+
'aws --region ', Ref('AWS::Region'), ' ec2 associate-address --allocation-id ', FnGetAtt('VpnIPAddress','AllocationId') ," --instance-id ${INSTANCE_ID}\n",
|
195
|
+
"sleep 3\n",
|
196
|
+
"mkdir /data \n",
|
197
|
+
"e2fsck -fy /dev/xvdb ; if [ $? -eq 8 ]; then mkfs.ext4 /dev/xvdb && mount /dev/xvdb /data; else mount /dev/xvdb /data; fi\n",
|
198
|
+
"service docker start\n",
|
199
|
+
"start ecs\n",
|
200
|
+
]))
|
201
|
+
}
|
202
|
+
|
203
|
+
AutoScalingGroup('AutoScaleGroup') {
|
204
|
+
UpdatePolicy('AutoScalingRollingUpdate', {
|
205
|
+
'MinInstancesInService' => '0',
|
206
|
+
'MaxBatchSize' => '1',
|
207
|
+
})
|
208
|
+
LaunchConfigurationName Ref('LaunchConfig')
|
209
|
+
HealthCheckGracePeriod '500'
|
210
|
+
HealthCheckType 'EC2'
|
211
|
+
MinSize 1
|
212
|
+
MaxSize 1
|
213
|
+
VPCZoneIdentifier [ Ref('SubnetPublicA') ]
|
214
|
+
addTag('Name', FnJoin('-',[Ref('EnvironmentName'), 'vpn' , 'xx']), true)
|
215
|
+
addTag('Environment', Ref('EnvironmentName'), true)
|
216
|
+
addTag('EnvironmentType', Ref('EnvironmentType'), true)
|
217
|
+
addTag('Role', 'vpn', true)
|
218
|
+
}
|
219
|
+
|
220
|
+
Route53_RecordSet('VpnRecordSet') {
|
221
|
+
DependsOn ['VpnIPAddress']
|
222
|
+
HostedZoneName FnJoin('', [ dns_domain, '.' ])
|
223
|
+
Comment 'Vpn record set'
|
224
|
+
Name FnJoin('', [ 'opvn.', dns_domain, '.' ])
|
225
|
+
Type 'A'
|
226
|
+
TTL '60'
|
227
|
+
ResourceRecords [ Ref('VpnIPAddress') ]
|
228
|
+
}
|
229
|
+
|
230
|
+
ECS_TaskDefinition('OpenVpnTask') {
|
231
|
+
ContainerDefinitions([
|
232
|
+
{
|
233
|
+
Name: 'openvpn',
|
234
|
+
MemoryReservation: '1024',
|
235
|
+
Cpu: '1024',
|
236
|
+
Image: 'base2/openvpn-as',
|
237
|
+
Essential: true,
|
238
|
+
Privileged: true,
|
239
|
+
MountPoints: [
|
240
|
+
{
|
241
|
+
ContainerPath: '/etc/localtime',
|
242
|
+
SourceVolume: 'timezone',
|
243
|
+
ReadOnly: true
|
244
|
+
},
|
245
|
+
{
|
246
|
+
ContainerPath: '/config',
|
247
|
+
SourceVolume: 'data',
|
248
|
+
ReadOnly: false
|
249
|
+
}
|
250
|
+
]
|
251
|
+
}
|
252
|
+
])
|
253
|
+
NetworkMode 'host'
|
254
|
+
Volumes([
|
255
|
+
{
|
256
|
+
Name: 'timezone',
|
257
|
+
Host: {
|
258
|
+
SourcePath: '/etc/localtime'
|
259
|
+
}
|
260
|
+
},
|
261
|
+
{
|
262
|
+
Name: 'data',
|
263
|
+
Host: {
|
264
|
+
SourcePath: '/data'
|
265
|
+
}
|
266
|
+
}
|
267
|
+
])
|
268
|
+
}
|
269
|
+
|
270
|
+
ECS_Service('OpenVpnService') {
|
271
|
+
Cluster Ref('CiinaboxVpn')
|
272
|
+
DesiredCount 1
|
273
|
+
DeploymentConfiguration({
|
274
|
+
MaximumPercent: 100,
|
275
|
+
MinimumHealthyPercent: 0
|
276
|
+
})
|
277
|
+
TaskDefinition Ref('OpenVpnTask')
|
278
|
+
}
|
279
|
+
|
280
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ciinabox-ecs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.10.alpha.1529494989
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Base2Services
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -24,34 +24,62 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '12'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: aws-sdk-s3
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: aws-sdk-cloudformation
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: cfndsl
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
59
|
- - "~>"
|
32
60
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
61
|
+
version: '0.16'
|
34
62
|
type: :runtime
|
35
63
|
prerelease: false
|
36
64
|
version_requirements: !ruby/object:Gem::Requirement
|
37
65
|
requirements:
|
38
66
|
- - "~>"
|
39
67
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
68
|
+
version: '0.16'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: cfn_manage
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
44
72
|
requirements:
|
45
73
|
- - "~>"
|
46
74
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0
|
75
|
+
version: '0'
|
48
76
|
type: :runtime
|
49
77
|
prerelease: false
|
50
78
|
version_requirements: !ruby/object:Gem::Requirement
|
51
79
|
requirements:
|
52
80
|
- - "~>"
|
53
81
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0
|
82
|
+
version: '0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: deep_merge
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -104,7 +132,6 @@ files:
|
|
104
132
|
- ext/helper.rb
|
105
133
|
- ext/policies.rb
|
106
134
|
- ext/zip_helper.rb
|
107
|
-
- lambdas/acm_issuer_validator/install.sh
|
108
135
|
- lambdas/acm_issuer_validator/lib/install.sh
|
109
136
|
- lib/ciinabox-ecs.rb
|
110
137
|
- templates/bastion.rb
|
@@ -120,6 +147,7 @@ files:
|
|
120
147
|
- templates/services/jenkins.rb
|
121
148
|
- templates/services/nexus.rb
|
122
149
|
- templates/vpc.rb
|
150
|
+
- templates/vpn.rb
|
123
151
|
homepage: https://github.com/base2Services/ciinabox-ecs
|
124
152
|
licenses:
|
125
153
|
- MIT
|
@@ -135,12 +163,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
135
163
|
version: '0'
|
136
164
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
165
|
requirements:
|
138
|
-
- - "
|
166
|
+
- - ">"
|
139
167
|
- !ruby/object:Gem::Version
|
140
|
-
version:
|
168
|
+
version: 1.3.1
|
141
169
|
requirements: []
|
142
170
|
rubyforge_project:
|
143
|
-
rubygems_version: 2.7.
|
171
|
+
rubygems_version: 2.7.7
|
144
172
|
signing_key:
|
145
173
|
specification_version: 4
|
146
174
|
summary: Manage ciinabox on Aws Ecs
|