ciinabox-ecs 0.1.6
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 +7 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +458 -0
- data/Rakefile +649 -0
- data/bin/Rakefile +1 -0
- data/bin/ciinabox-ecs +2 -0
- data/bin/ciinabox-ecs.rb +60 -0
- data/config/ciinabox_params.yml.erb +71 -0
- data/config/default_lambdas.yml +26 -0
- data/config/default_params.yml +303 -0
- data/config/default_params.yml.example +124 -0
- data/config/default_services.yml +62 -0
- data/ext/common_helper.rb +21 -0
- data/ext/config/managed_policies.yml +156 -0
- data/ext/helper.rb +29 -0
- data/ext/policies.rb +53 -0
- data/ext/zip_helper.rb +57 -0
- data/lambdas/acm_issuer_validator/lib/install.sh +20 -0
- data/templates/bastion.rb +121 -0
- data/templates/ciinabox.rb +159 -0
- data/templates/ecs-cluster.rb +252 -0
- data/templates/ecs-services.rb +340 -0
- data/templates/lambdas.rb +172 -0
- data/templates/services/bitbucket.rb +81 -0
- data/templates/services/drone.rb +394 -0
- data/templates/services/hawtio.rb +100 -0
- data/templates/services/icinga2.rb +79 -0
- data/templates/services/jenkins.rb +209 -0
- data/templates/services/nexus.rb +96 -0
- data/templates/vpc.rb +290 -0
- metadata +144 -0
@@ -0,0 +1,124 @@
|
|
1
|
+
#Sample file of what your params.yml file should include
|
2
|
+
|
3
|
+
#ciinabox default config
|
4
|
+
ciinabox_version: 0.1
|
5
|
+
|
6
|
+
ciinabox_name: example
|
7
|
+
|
8
|
+
aws_profile: example
|
9
|
+
|
10
|
+
aws_region: us-east-1
|
11
|
+
|
12
|
+
aws_account_id: 198712987398
|
13
|
+
|
14
|
+
#override S3 bucket location
|
15
|
+
source_bucket: source.aws.example.com
|
16
|
+
|
17
|
+
#add if you want ecs docker volume != 22GB - must be > 22
|
18
|
+
#ecs_docker_volume_size: 100
|
19
|
+
|
20
|
+
#use this to change volume snapshot for running ciinabox
|
21
|
+
#ecs_data_volume_name: "ECSDataVolume2s"
|
22
|
+
|
23
|
+
#set the size of the ecs data volume -- NOTE: would take a new volume - i.e. change volume name
|
24
|
+
#ecs_data_volume_size: 250
|
25
|
+
|
26
|
+
#set the snapshot to restore from
|
27
|
+
#ecs_data_volume_snapshot: snap-49e2b3b5
|
28
|
+
|
29
|
+
#optional ciinabox name if you need more than one or you want a different name
|
30
|
+
#stack_name: ciinabox-tools
|
31
|
+
|
32
|
+
#for internal elb for jenkins
|
33
|
+
#internal_elb: false
|
34
|
+
|
35
|
+
#ciinabox ECS cluster name
|
36
|
+
cluster_name: ciinabox
|
37
|
+
|
38
|
+
#log level - change to :debug to see the AWS commands being executed
|
39
|
+
log_level: :info
|
40
|
+
|
41
|
+
#change this to your own dns_domain
|
42
|
+
#domain needs to be manage via route53 since the cloudformation adds additional records
|
43
|
+
dns_domain: tools.aws.example.com
|
44
|
+
|
45
|
+
#icinga2_image: AWS_ACCOUNT_ID.dkr.ecr.AWS_REGION/base2/icinga2:VERSION_TAG
|
46
|
+
|
47
|
+
#AWS Availability Zones Idenifers
|
48
|
+
availability_zones:
|
49
|
+
- 'A'
|
50
|
+
- 'B'
|
51
|
+
|
52
|
+
azId:
|
53
|
+
A: 0
|
54
|
+
B: 1
|
55
|
+
C: 2
|
56
|
+
D: 3
|
57
|
+
E: 4
|
58
|
+
|
59
|
+
#ciinabox environment config
|
60
|
+
Mappings:
|
61
|
+
EnvironmentType:
|
62
|
+
ciinabox:
|
63
|
+
KeyName: ciinabox
|
64
|
+
SSLCertARN: "arn:aws:iam::198712987398:server-certificate/ciinabox"
|
65
|
+
NetworkPrefix: 10
|
66
|
+
StackOctet: 150
|
67
|
+
StackMask: 16
|
68
|
+
SubnetMask: 26
|
69
|
+
NatInstanceType: t2.micro
|
70
|
+
ECSInstanceType: t2.large
|
71
|
+
|
72
|
+
#Subnet offsets 10.150.x.0/26
|
73
|
+
vpc:
|
74
|
+
SubnetOctetA: "0"
|
75
|
+
SubnetOctetB: "1"
|
76
|
+
ecs:
|
77
|
+
SubnetOctetA: "2"
|
78
|
+
SubnetOctetB: "3"
|
79
|
+
|
80
|
+
#Amazon Linux AMI 2015.03.1 (HVM), SSD Volume Type
|
81
|
+
natAMI:
|
82
|
+
us-east-1:
|
83
|
+
ami: ami-60b6c60a
|
84
|
+
us-west-2:
|
85
|
+
ami: ami-f0091d91
|
86
|
+
ap-southeast-2:
|
87
|
+
ami: ami-48d38c2b
|
88
|
+
eu-west-1:
|
89
|
+
ami: ami-bff32ccc
|
90
|
+
|
91
|
+
ecs_ami:
|
92
|
+
us-east-1:
|
93
|
+
ami: ami-cb2305a1
|
94
|
+
us-west-2:
|
95
|
+
ami: ami-ec75908c
|
96
|
+
ap-southeast-2:
|
97
|
+
ami: ami-83af8ae0
|
98
|
+
eu-west-1:
|
99
|
+
ami: ami-13f84d60
|
100
|
+
|
101
|
+
#Environment Access
|
102
|
+
#add list of public IP addresses you want to access the environment from
|
103
|
+
#default to public access probably best to change this
|
104
|
+
opsAccess:
|
105
|
+
- 44.33.123.223/32
|
106
|
+
|
107
|
+
#add list of public IP addresses for your developers to access the environment
|
108
|
+
#default to public access probably best to change this
|
109
|
+
devAccess:
|
110
|
+
- 213.120.111.2/32 #Example
|
111
|
+
|
112
|
+
# Upload a default ssl cert to AWS to be used by default to ciinabox service ELBs
|
113
|
+
default_ssl_cert_id: "arn:aws:iam::198712987398:server-certificate/ciinabox"
|
114
|
+
|
115
|
+
|
116
|
+
#extra_stacks:
|
117
|
+
# elk:
|
118
|
+
# #define template name? - optional
|
119
|
+
# file_name: elk
|
120
|
+
# parameters:
|
121
|
+
# RoleName: search
|
122
|
+
# CertName: x
|
123
|
+
# SubnetOctetA: 11
|
124
|
+
# SubnetOctetB: 12
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# ciinabox services default configuration
|
2
|
+
|
3
|
+
services:
|
4
|
+
- jenkins:
|
5
|
+
# Optional Jenkins Service Parameters
|
6
|
+
# ContainerImage: base2/ciinabox-jenkins:2.0
|
7
|
+
# ContainerMemory: 4096
|
8
|
+
# ContainerCPU: 300
|
9
|
+
# JAVA_OPTS: -Xmx4096m
|
10
|
+
# you only need to add these ports for JNLP slaves
|
11
|
+
# LoadBalancerPort: 50000
|
12
|
+
# InstancePort: 50000
|
13
|
+
# Protocol: TCP
|
14
|
+
|
15
|
+
#example for Internal Port for Jenkins
|
16
|
+
# - jenkins:
|
17
|
+
# LoadBalancerPort: 50000
|
18
|
+
# InstancePort: 50000
|
19
|
+
# Protocol: TCP
|
20
|
+
# needs internal_elb: true
|
21
|
+
# will trigger this 2nd hostname for jenkins internal-jenkins.#{dns_domain}
|
22
|
+
|
23
|
+
#example for drone
|
24
|
+
# - drone:
|
25
|
+
# params:
|
26
|
+
# -
|
27
|
+
# VPC:
|
28
|
+
# Ref: VPC
|
29
|
+
# -
|
30
|
+
# SubnetPublicA:
|
31
|
+
# Ref: SubnetPublicA
|
32
|
+
# -
|
33
|
+
# SubnetPublicB:
|
34
|
+
# Ref: SubnetPublicB
|
35
|
+
# -
|
36
|
+
# ECSSubnetPrivateA:
|
37
|
+
# Ref: ECSSubnetPrivateA
|
38
|
+
# -
|
39
|
+
# ECSSubnetPrivateB:
|
40
|
+
# Ref: ECSSubnetPrivateB
|
41
|
+
# -
|
42
|
+
# SecurityGroupBackplane:
|
43
|
+
# Ref: SecurityGroupBackplane
|
44
|
+
# -
|
45
|
+
# SecurityGroupOps:
|
46
|
+
# Ref: SecurityGroupOps
|
47
|
+
# -
|
48
|
+
# SecurityGroupDev:
|
49
|
+
# Ref: SecurityGroupDev
|
50
|
+
# -
|
51
|
+
# SecurityGroupNatGateway:
|
52
|
+
# Ref: SecurityGroupNatGateway
|
53
|
+
# -
|
54
|
+
# SecurityGroupWebHooks:
|
55
|
+
# Ref: SecurityGroupWebHooks
|
56
|
+
# -
|
57
|
+
# ECSENIPrivateIpAddress:
|
58
|
+
# Ref: ECSENIPrivateIpAddress
|
59
|
+
# tasks:
|
60
|
+
# drone-server:
|
61
|
+
# env:
|
62
|
+
# DRONE_OPEN: true
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class ::Hash
|
2
|
+
def deep_merge(second)
|
3
|
+
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 }
|
4
|
+
self.merge(second.to_h, &merger)
|
5
|
+
end
|
6
|
+
|
7
|
+
|
8
|
+
def extend(second)
|
9
|
+
second.each { |k, v|
|
10
|
+
|
11
|
+
if ((self.key? k) and (v.is_a? Hash and self[k].is_a? Hash))
|
12
|
+
self[k].extend(v)
|
13
|
+
else
|
14
|
+
self[k] = v
|
15
|
+
end
|
16
|
+
|
17
|
+
} if second.is_a? Hash
|
18
|
+
|
19
|
+
self
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
ec2-describe:
|
2
|
+
action:
|
3
|
+
- ec2:Describe*
|
4
|
+
- autoscaling:Describe*
|
5
|
+
- elasticloadbalancing:Describe*
|
6
|
+
|
7
|
+
cloudwatch-logs:
|
8
|
+
action:
|
9
|
+
- logs:CreateLogGroup
|
10
|
+
- logs:CreateLogStream
|
11
|
+
- logs:PutLogEvents
|
12
|
+
- logs:DescribeLogStreams
|
13
|
+
- logs:DescribeLogGroups
|
14
|
+
resource:
|
15
|
+
- arn:aws:logs:*:*:*
|
16
|
+
|
17
|
+
cloudwatch-monitoring:
|
18
|
+
action:
|
19
|
+
- cloudwatch:PutMetricData
|
20
|
+
- cloudwatch:GetMetricStatistics
|
21
|
+
- cloudwatch:ListMetrics
|
22
|
+
|
23
|
+
s3-list-buckets:
|
24
|
+
action:
|
25
|
+
- s3:ListAllMyBuckets
|
26
|
+
- s3:ListBucket
|
27
|
+
|
28
|
+
s3-chef-ro:
|
29
|
+
action:
|
30
|
+
- s3:Get*
|
31
|
+
- s3:List*
|
32
|
+
resource:
|
33
|
+
- arn:aws:s3:::%{source_bucket}/chef
|
34
|
+
- arn:aws:s3:::%{source_bucket}/chef/*
|
35
|
+
|
36
|
+
s3-environment-ro:
|
37
|
+
action:
|
38
|
+
- s3:Get*
|
39
|
+
- s3:List*
|
40
|
+
resource:
|
41
|
+
- arn:aws:s3:::%{source_bucket}/chef-environments
|
42
|
+
- arn:aws:s3:::%{source_bucket}/chef-environments/*
|
43
|
+
|
44
|
+
s3-codedeploy-ro:
|
45
|
+
action:
|
46
|
+
- s3:Get*
|
47
|
+
- s3:List*
|
48
|
+
resource:
|
49
|
+
- arn:aws:s3:::%{source_bucket}/codedeploy
|
50
|
+
- arn:aws:s3:::%{source_bucket}/codedeploy/*
|
51
|
+
|
52
|
+
ecs-service-role:
|
53
|
+
action:
|
54
|
+
- ecs:CreateCluster
|
55
|
+
- ecs:DeregisterContainerInstance
|
56
|
+
- ecs:DiscoverPollEndpoint
|
57
|
+
- ecs:Poll
|
58
|
+
- ecs:RegisterContainerInstance
|
59
|
+
- ecs:StartTelemetrySession
|
60
|
+
- ecs:Submit*
|
61
|
+
- ec2:AuthorizeSecurityGroupIngress
|
62
|
+
- ec2:Describe*
|
63
|
+
- elasticloadbalancing:DeregisterInstancesFromLoadBalancer
|
64
|
+
- elasticloadbalancing:Describe*
|
65
|
+
- elasticloadbalancing:RegisterInstancesWithLoadBalancer
|
66
|
+
- autoscaling:Describe*
|
67
|
+
|
68
|
+
ecr-pull-images:
|
69
|
+
action:
|
70
|
+
- ecr:BatchCheckLayerAvailability
|
71
|
+
- ecr:BatchGetImage
|
72
|
+
- ecr:Get*
|
73
|
+
- ecr:List*
|
74
|
+
|
75
|
+
attach-ebs-volume:
|
76
|
+
action:
|
77
|
+
- ec2:DescribeVolumes
|
78
|
+
- ec2:AttachVolume
|
79
|
+
- ec2:DetachVolume
|
80
|
+
|
81
|
+
attach-network-interface:
|
82
|
+
action:
|
83
|
+
- ec2:DescribeNetworkInterfaces
|
84
|
+
- ec2:AttachNetworkInterface
|
85
|
+
- ec2:DetachNetworkInterface
|
86
|
+
|
87
|
+
associate-address:
|
88
|
+
action:
|
89
|
+
- ec2:AssociateAddress
|
90
|
+
|
91
|
+
ssm:
|
92
|
+
action:
|
93
|
+
- ssm:DescribeAssociation
|
94
|
+
- ssm:GetDeployablePatchSnapshotForInstance
|
95
|
+
- ssm:GetDocument
|
96
|
+
- ssm:GetParameters
|
97
|
+
- ssm:ListAssociations
|
98
|
+
- ssm:ListInstanceAssociations
|
99
|
+
- ssm:PutInventory
|
100
|
+
- ssm:UpdateAssociationStatus
|
101
|
+
- ssm:UpdateInstanceAssociationStatus
|
102
|
+
- ssm:UpdateInstanceInformation
|
103
|
+
|
104
|
+
ec2messages:
|
105
|
+
action:
|
106
|
+
- ec2messages:AcknowledgeMessage
|
107
|
+
- ec2messages:DeleteMessage
|
108
|
+
- ec2messages:FailMessage
|
109
|
+
- ec2messages:GetEndpoint
|
110
|
+
- ec2messages:GetMessages
|
111
|
+
- ec2messages:SendReply
|
112
|
+
|
113
|
+
s3-secrets-ro:
|
114
|
+
action:
|
115
|
+
- s3:Get*
|
116
|
+
- s3:List*
|
117
|
+
resource:
|
118
|
+
- Fn::Join:
|
119
|
+
- ""
|
120
|
+
-
|
121
|
+
- 'arn:aws:s3:::'
|
122
|
+
- Fn::FindInMap:
|
123
|
+
- 'Secrets'
|
124
|
+
- Ref: 'EnvironmentType'
|
125
|
+
- 'bucket'
|
126
|
+
- '/'
|
127
|
+
- Fn::FindInMap:
|
128
|
+
- 'Secrets'
|
129
|
+
- Ref: 'EnvironmentType'
|
130
|
+
- 'key'
|
131
|
+
- '/'
|
132
|
+
- Ref: "EnvironmentName"
|
133
|
+
- '/*'
|
134
|
+
|
135
|
+
route53-manage-records:
|
136
|
+
action:
|
137
|
+
- route53:ListTagsForResources
|
138
|
+
- route53:GetHostedZone
|
139
|
+
- route53:ListHostedZones
|
140
|
+
- route53:ListHostedZonesByName
|
141
|
+
- route53:ChangeResourceRecordSets
|
142
|
+
- route53:ListResourceRecordSets
|
143
|
+
- route53:ListTagsForResource
|
144
|
+
|
145
|
+
acm-cert-issue:
|
146
|
+
action:
|
147
|
+
- acm:DeleteCertificate
|
148
|
+
- acm:DescribeCertificate
|
149
|
+
- acm:DescribeCertificate
|
150
|
+
- acm:RequestCertificate
|
151
|
+
- acm:ListCertificates
|
152
|
+
|
153
|
+
lambda-invoke:
|
154
|
+
action:
|
155
|
+
- lambda:Get*
|
156
|
+
- lambda:Invoke*
|
data/ext/helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# ciinabox cfndsl helpers
|
2
|
+
def add_security_group_rules (access_list)
|
3
|
+
rules = []
|
4
|
+
access_list.each do |ip|
|
5
|
+
rules << { IpProtocol: 'tcp', FromPort: '22', ToPort: '22', CidrIp: ip }
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def nat_scale_up_schedule(scale_up_schedule)
|
10
|
+
expr = scale_up_schedule.split
|
11
|
+
hour = expr[1].to_i
|
12
|
+
minute = expr[0].to_i
|
13
|
+
if minute < 10
|
14
|
+
minute = 60 + minute - 10
|
15
|
+
hour = hour - 1
|
16
|
+
else
|
17
|
+
minute = minute - 10
|
18
|
+
end
|
19
|
+
return "#{minute} #{hour} #{expr[2]} #{expr[3]} #{expr[4]}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def lookup_service(name, services=[])
|
23
|
+
services.each do |service|
|
24
|
+
if service.has_key? name
|
25
|
+
return service[name]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
nil
|
29
|
+
end
|
data/ext/policies.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Configs
|
4
|
+
class << self; attr_accessor :managed_policies, :all end
|
5
|
+
script_dir = File.expand_path File.dirname(__FILE__)
|
6
|
+
@managed_policies = YAML.load(File.read("#{script_dir}/config/managed_policies.yml"))
|
7
|
+
@all = Hash.new.tap { |h| Dir['config/*.yml'].each { |yml| h.merge!(YAML.load(File.open(yml))) }}
|
8
|
+
# Override with ciinabox configs
|
9
|
+
ciinaboxes_dir = ENV['CIINABOXES_DIR'] || 'ciinaboxes'
|
10
|
+
ciinabox_name = ENV['CIINABOX'] || ''
|
11
|
+
(Dir["#{ciinaboxes_dir}/#{ciinabox_name}/config/*.yml"]).each { |yml|
|
12
|
+
@all.merge!(YAML.load(File.open(yml)))
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
class Policies
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@policy_array = Array.new
|
20
|
+
@config = Configs.all
|
21
|
+
@policies = (@config.key?('custom_policies') ? Configs.managed_policies.merge(@config['custom_policies']) : Configs.managed_policies)
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_policies(group = nil)
|
25
|
+
create_policies(@config['default_policies']) if @config.key?('default_policies')
|
26
|
+
create_policies(@config['group_policies'][group]) unless group.nil?
|
27
|
+
return @policy_array
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_policies(policies)
|
31
|
+
policies.each do |policy|
|
32
|
+
raise "ERROR: #{policy} policy doesn't exist in the managed policies or as a custom policy" unless @policies.key?(policy)
|
33
|
+
resource = (@policies[policy].key?('resource') ? gsub_yml(@policies[policy]['resource']) : ["*"])
|
34
|
+
@policy_array << { PolicyName: policy, PolicyDocument: { Statement: [ { Effect:"Allow", Action: @policies[policy]['action'], Resource: resource }]} }
|
35
|
+
end
|
36
|
+
return @policy_array
|
37
|
+
end
|
38
|
+
|
39
|
+
# replaces %{variables} in the yml
|
40
|
+
def gsub_yml(resource)
|
41
|
+
replaced = []
|
42
|
+
resource.each { |r|
|
43
|
+
if r.is_a? String
|
44
|
+
replaced << r.gsub('%{source_bucket}', @config['source_bucket'])
|
45
|
+
else
|
46
|
+
replaced << r
|
47
|
+
end
|
48
|
+
}
|
49
|
+
|
50
|
+
return replaced
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|