formatron 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.rubocop.yml +3 -0
- data/.simplecov +7 -0
- data/.travis.yml +17 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +6 -0
- data/Guardfile +16 -0
- data/LICENSE.txt +21 -0
- data/README.md +93 -0
- data/Rakefile +16 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/exe/formatron +20 -0
- data/formatron.gemspec +52 -0
- data/lib/formatron.rb +357 -0
- data/lib/formatron/aws.rb +197 -0
- data/lib/formatron/chef.rb +156 -0
- data/lib/formatron/chef/berkshelf.rb +55 -0
- data/lib/formatron/chef/keys.rb +48 -0
- data/lib/formatron/chef/knife.rb +169 -0
- data/lib/formatron/chef_clients.rb +73 -0
- data/lib/formatron/cli.rb +33 -0
- data/lib/formatron/cli/completion.rb +26 -0
- data/lib/formatron/cli/deploy.rb +57 -0
- data/lib/formatron/cli/destroy.rb +57 -0
- data/lib/formatron/cli/generators/bootstrap.rb +250 -0
- data/lib/formatron/cli/generators/credentials.rb +100 -0
- data/lib/formatron/cli/generators/instance.rb +118 -0
- data/lib/formatron/cli/provision.rb +59 -0
- data/lib/formatron/cloud_formation.rb +54 -0
- data/lib/formatron/cloud_formation/resources/cloud_formation.rb +27 -0
- data/lib/formatron/cloud_formation/resources/ec2.rb +336 -0
- data/lib/formatron/cloud_formation/resources/iam.rb +94 -0
- data/lib/formatron/cloud_formation/resources/route53.rb +54 -0
- data/lib/formatron/cloud_formation/scripts.rb +128 -0
- data/lib/formatron/cloud_formation/template.rb +114 -0
- data/lib/formatron/cloud_formation/template/parameters.rb +20 -0
- data/lib/formatron/cloud_formation/template/vpc.rb +181 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet.rb +187 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/acl.rb +147 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/bastion.rb +66 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/chef_server.rb +205 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/instance.rb +162 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/instance/policy.rb +74 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/instance/security_group.rb +117 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/instance/setup.rb +68 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/nat.rb +94 -0
- data/lib/formatron/completion.rb +26 -0
- data/lib/formatron/completion/completion.sh.erb +35 -0
- data/lib/formatron/config.rb +31 -0
- data/lib/formatron/config/reader.rb +29 -0
- data/lib/formatron/dsl.rb +15 -0
- data/lib/formatron/dsl/formatron.rb +25 -0
- data/lib/formatron/dsl/formatron/global.rb +19 -0
- data/lib/formatron/dsl/formatron/global/ec2.rb +17 -0
- data/lib/formatron/dsl/formatron/vpc.rb +17 -0
- data/lib/formatron/dsl/formatron/vpc/subnet.rb +27 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/acl.rb +18 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/chef_server.rb +32 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/chef_server/organization.rb +22 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/instance.rb +29 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/instance/chef.rb +22 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/instance/policy.rb +21 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/instance/policy/statement.rb +23 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/instance/security_group.rb +21 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/instance/setup.rb +22 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/instance/setup/variable.rb +23 -0
- data/lib/formatron/external.rb +61 -0
- data/lib/formatron/external/dsl.rb +171 -0
- data/lib/formatron/external/outputs.rb +25 -0
- data/lib/formatron/generators/bootstrap.rb +90 -0
- data/lib/formatron/generators/bootstrap/config.rb +62 -0
- data/lib/formatron/generators/bootstrap/ec2.rb +17 -0
- data/lib/formatron/generators/bootstrap/formatronfile.rb +52 -0
- data/lib/formatron/generators/bootstrap/formatronfile/Formatronfile.erb +79 -0
- data/lib/formatron/generators/bootstrap/ssl.rb +35 -0
- data/lib/formatron/generators/credentials.rb +17 -0
- data/lib/formatron/generators/instance.rb +64 -0
- data/lib/formatron/generators/instance/config.rb +47 -0
- data/lib/formatron/generators/instance/formatronfile.rb +47 -0
- data/lib/formatron/generators/instance/formatronfile/Formatronfile.erb +16 -0
- data/lib/formatron/generators/util.rb +14 -0
- data/lib/formatron/generators/util/cookbook.rb +65 -0
- data/lib/formatron/generators/util/gitignore.rb +16 -0
- data/lib/formatron/generators/util/readme.rb +18 -0
- data/lib/formatron/logger.rb +8 -0
- data/lib/formatron/s3/chef_server_cert.rb +85 -0
- data/lib/formatron/s3/chef_server_keys.rb +103 -0
- data/lib/formatron/s3/cloud_formation_template.rb +61 -0
- data/lib/formatron/s3/configuration.rb +58 -0
- data/lib/formatron/s3/path.rb +30 -0
- data/lib/formatron/util/dsl.rb +107 -0
- data/lib/formatron/util/shell.rb +20 -0
- data/lib/formatron/util/vpc.rb +15 -0
- data/lib/formatron/version.rb +4 -0
- data/support/cloudformation_describe_stacks_response.rb +36 -0
- data/support/dsl_test.rb +123 -0
- data/support/route53_get_hosted_zone_response.rb +21 -0
- data/support/s3_get_object_response.rb +21 -0
- data/support/template_test.rb +41 -0
- metadata +414 -0
@@ -0,0 +1,187 @@
|
|
1
|
+
require_relative 'subnet/nat'
|
2
|
+
require_relative 'subnet/bastion'
|
3
|
+
require_relative 'subnet/chef_server'
|
4
|
+
require_relative 'subnet/instance'
|
5
|
+
require_relative 'subnet/acl'
|
6
|
+
require_relative '../vpc'
|
7
|
+
require 'formatron/cloud_formation/resources/ec2'
|
8
|
+
|
9
|
+
class Formatron
|
10
|
+
module CloudFormation
|
11
|
+
class Template
|
12
|
+
class VPC
|
13
|
+
# generates CloudFormation subnet resources
|
14
|
+
# rubocop:disable Metrics/ClassLength
|
15
|
+
class Subnet
|
16
|
+
SUBNET_PREFIX = 'subnet'
|
17
|
+
SUBNET_ROUTE_TABLE_ASSOCIATION_PREFIX = 'subnetRouteTableAssociation'
|
18
|
+
|
19
|
+
# rubocop:disable Metrics/MethodLength
|
20
|
+
# rubocop:disable Metrics/ParameterLists
|
21
|
+
# rubocop:disable Metrics/AbcSize
|
22
|
+
def initialize(
|
23
|
+
subnet:,
|
24
|
+
external:,
|
25
|
+
vpc_guid:,
|
26
|
+
vpc_cidr:,
|
27
|
+
key_pair:,
|
28
|
+
hosted_zone_name:,
|
29
|
+
kms_key:,
|
30
|
+
nats:,
|
31
|
+
private_hosted_zone_id:,
|
32
|
+
public_hosted_zone_id:,
|
33
|
+
bucket:,
|
34
|
+
name:,
|
35
|
+
target:
|
36
|
+
)
|
37
|
+
@subnet = subnet
|
38
|
+
@external = external
|
39
|
+
@vpc_guid = vpc_guid
|
40
|
+
@vpc_cidr = vpc_cidr
|
41
|
+
@cidr = @subnet.cidr
|
42
|
+
@acl = @subnet.acl
|
43
|
+
@key_pair = key_pair
|
44
|
+
@hosted_zone_name = hosted_zone_name
|
45
|
+
@kms_key = kms_key
|
46
|
+
@nats = nats
|
47
|
+
@private_hosted_zone_id = private_hosted_zone_id
|
48
|
+
@public_hosted_zone_id = public_hosted_zone_id
|
49
|
+
@bucket = bucket
|
50
|
+
@name = name
|
51
|
+
@target = target
|
52
|
+
end
|
53
|
+
# rubocop:enable Metrics/AbcSize
|
54
|
+
# rubocop:enable Metrics/ParameterLists
|
55
|
+
# rubocop:enable Metrics/MethodLength
|
56
|
+
|
57
|
+
# rubocop:disable Metrics/MethodLength
|
58
|
+
def merge(resources:, outputs:)
|
59
|
+
@guid = @subnet.guid
|
60
|
+
if @guid.nil?
|
61
|
+
@guid = @external.guid
|
62
|
+
_merge_external resources: resources, outputs: outputs
|
63
|
+
else
|
64
|
+
_merge_local resources: resources, outputs: outputs
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def _merge_external(resources:, outputs:)
|
69
|
+
@gateway = @external.gateway
|
70
|
+
@availability_zone = @external.availability_zone
|
71
|
+
{
|
72
|
+
nat: NAT,
|
73
|
+
bastion: Bastion,
|
74
|
+
chef_server: ChefServer,
|
75
|
+
instance: Instance
|
76
|
+
}.each do |symbol, cls|
|
77
|
+
@subnet.send(symbol).each do |_, instance|
|
78
|
+
args = {
|
79
|
+
symbol => instance,
|
80
|
+
key_pair: @key_pair,
|
81
|
+
availability_zone: @availability_zone,
|
82
|
+
subnet_guid: @guid,
|
83
|
+
hosted_zone_name: @hosted_zone_name,
|
84
|
+
vpc_guid: @vpc_guid,
|
85
|
+
vpc_cidr: @vpc_cidr,
|
86
|
+
kms_key: @kms_key,
|
87
|
+
private_hosted_zone_id: @private_hosted_zone_id,
|
88
|
+
public_hosted_zone_id:
|
89
|
+
@gateway.nil? ? @public_hosted_zone_id : nil,
|
90
|
+
bucket: @bucket,
|
91
|
+
name: @name,
|
92
|
+
target: @target
|
93
|
+
}
|
94
|
+
instance = cls.new(**args)
|
95
|
+
instance.merge resources: resources, outputs: outputs
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def _merge_local(resources:, outputs:)
|
101
|
+
@subnet_id = "#{SUBNET_PREFIX}#{@guid}"
|
102
|
+
@subnet_route_table_association_id =
|
103
|
+
"#{SUBNET_ROUTE_TABLE_ASSOCIATION_PREFIX}#{@guid}"
|
104
|
+
@vpc_id = "#{VPC::VPC_PREFIX}#{@vpc_guid}"
|
105
|
+
@public_route_table_id =
|
106
|
+
"#{VPC::ROUTE_TABLE_PREFIX}#{@vpc_guid}"
|
107
|
+
@gateway = @subnet.gateway
|
108
|
+
@availability_zone = @subnet.availability_zone
|
109
|
+
{
|
110
|
+
nat: NAT,
|
111
|
+
bastion: Bastion,
|
112
|
+
chef_server: ChefServer,
|
113
|
+
instance: Instance
|
114
|
+
}.each do |symbol, cls|
|
115
|
+
@subnet.send(symbol).each do |_, instance|
|
116
|
+
args = {
|
117
|
+
symbol => instance,
|
118
|
+
key_pair: @key_pair,
|
119
|
+
availability_zone: @availability_zone,
|
120
|
+
subnet_guid: @guid,
|
121
|
+
hosted_zone_name: @hosted_zone_name,
|
122
|
+
vpc_guid: @vpc_guid,
|
123
|
+
vpc_cidr: @vpc_cidr,
|
124
|
+
kms_key: @kms_key,
|
125
|
+
private_hosted_zone_id: @private_hosted_zone_id,
|
126
|
+
public_hosted_zone_id:
|
127
|
+
@gateway.nil? ? @public_hosted_zone_id : nil,
|
128
|
+
bucket: @bucket,
|
129
|
+
name: @name,
|
130
|
+
target: @target
|
131
|
+
}
|
132
|
+
instance = cls.new(**args)
|
133
|
+
instance.merge resources: resources, outputs: outputs
|
134
|
+
end
|
135
|
+
end
|
136
|
+
_add_subnet resources, outputs
|
137
|
+
_add_subnet_route_table_association resources
|
138
|
+
_add_acl resources if @acl && @gateway.nil?
|
139
|
+
end
|
140
|
+
# rubocop:enable Metrics/MethodLength
|
141
|
+
|
142
|
+
def _add_subnet(resources, outputs)
|
143
|
+
resources[@subnet_id] = Resources::EC2.subnet(
|
144
|
+
vpc: @vpc_id,
|
145
|
+
cidr: @cidr,
|
146
|
+
availability_zone: @availability_zone,
|
147
|
+
map_public_ip_on_launch: @gateway.nil?
|
148
|
+
)
|
149
|
+
outputs[@subnet_id] = Template.output Template.ref(@subnet_id)
|
150
|
+
end
|
151
|
+
|
152
|
+
def _add_subnet_route_table_association(resources)
|
153
|
+
route_table = @public_route_table_id
|
154
|
+
unless @gateway.nil?
|
155
|
+
gateway_guid = @nats[@gateway].guid
|
156
|
+
route_table = "#{NAT::ROUTE_TABLE_PREFIX}#{gateway_guid}"
|
157
|
+
end
|
158
|
+
resources[@subnet_route_table_association_id] =
|
159
|
+
Resources::EC2.subnet_route_table_association(
|
160
|
+
route_table: route_table,
|
161
|
+
subnet: @subnet_id
|
162
|
+
)
|
163
|
+
end
|
164
|
+
|
165
|
+
def _add_acl(resources)
|
166
|
+
acl = ACL.new(
|
167
|
+
acl: @acl,
|
168
|
+
subnet_guid: @guid,
|
169
|
+
vpc_guid: @vpc_guid,
|
170
|
+
vpc_cidr: @vpc_cidr
|
171
|
+
)
|
172
|
+
acl.merge resources: resources
|
173
|
+
end
|
174
|
+
|
175
|
+
private(
|
176
|
+
:_merge_local,
|
177
|
+
:_merge_external,
|
178
|
+
:_add_subnet,
|
179
|
+
:_add_subnet_route_table_association,
|
180
|
+
:_add_acl
|
181
|
+
)
|
182
|
+
end
|
183
|
+
# rubocop:enable Metrics/ClassLength
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'formatron/cloud_formation/resources/ec2'
|
2
|
+
|
3
|
+
class Formatron
|
4
|
+
module CloudFormation
|
5
|
+
class Template
|
6
|
+
class VPC
|
7
|
+
class Subnet
|
8
|
+
# generates CloudFormation ACL resources
|
9
|
+
# rubocop:disable Metrics/ClassLength
|
10
|
+
class ACL
|
11
|
+
NETWORK_ACL_PREFIX = 'networkAcl'
|
12
|
+
SUBNET_NETWORK_ACL_ASSOCIATION_PREFIX =
|
13
|
+
'subnetNetworkAclAssociation'
|
14
|
+
VPC_INBOUND_NETWORK_ACL_ENTRY_PREFIX =
|
15
|
+
'vpcInboundNetworkAclEntry'
|
16
|
+
EXTERNAL_INBOUND_TCP_NETWORK_ACL_ENTRY_PREFIX =
|
17
|
+
'externalInboundTcpNetworkAclEntry'
|
18
|
+
EXTERNAL_INBOUND_UDP_NETWORK_ACL_ENTRY_PREFIX =
|
19
|
+
'externalInboundUdpNetworkAclEntry'
|
20
|
+
OUTBOUND_NETWORK_ACL_ENTRY_PREFIX =
|
21
|
+
'outboundNetworkAclEntry'
|
22
|
+
EXTERNAL_INBOUND_NETWORK_ACL_ENTRY_PREFIX =
|
23
|
+
'externalInboundNetworkAclEntry'
|
24
|
+
|
25
|
+
EPHEMERAL_PORT_START = 1024
|
26
|
+
EPHEMERAL_PORT_END = 65_535
|
27
|
+
|
28
|
+
# rubocop:disable Metrics/MethodLength
|
29
|
+
def initialize(acl:, subnet_guid:, vpc_guid:, vpc_cidr:)
|
30
|
+
@acl = acl
|
31
|
+
@subnet_guid = subnet_guid
|
32
|
+
@vpc_guid = vpc_guid
|
33
|
+
@vpc_cidr = vpc_cidr
|
34
|
+
@network_acl_id = "#{NETWORK_ACL_PREFIX}#{@subnet_guid}"
|
35
|
+
@subnet_network_acl_association_id =
|
36
|
+
"#{SUBNET_NETWORK_ACL_ASSOCIATION_PREFIX}#{@subnet_guid}"
|
37
|
+
@vpc_id = "#{VPC::VPC_PREFIX}#{@vpc_guid}"
|
38
|
+
@subnet_id = "#{Subnet::SUBNET_PREFIX}#{@subnet_guid}"
|
39
|
+
@network_acl_entry_vpc_inbound_id =
|
40
|
+
"#{VPC_INBOUND_NETWORK_ACL_ENTRY_PREFIX}#{@subnet_guid}"
|
41
|
+
@network_acl_entry_external_inbound_tcp_id =
|
42
|
+
"#{EXTERNAL_INBOUND_TCP_NETWORK_ACL_ENTRY_PREFIX}" \
|
43
|
+
"#{@subnet_guid}"
|
44
|
+
@network_acl_entry_external_inbound_udp_id =
|
45
|
+
"#{EXTERNAL_INBOUND_UDP_NETWORK_ACL_ENTRY_PREFIX}" \
|
46
|
+
"#{@subnet_guid}"
|
47
|
+
@network_acl_entry_outbound_id =
|
48
|
+
"#{OUTBOUND_NETWORK_ACL_ENTRY_PREFIX}#{@subnet_guid}"
|
49
|
+
@source_cidrs = @acl.source_cidr
|
50
|
+
end
|
51
|
+
# rubocop:enable Metrics/MethodLength
|
52
|
+
|
53
|
+
def merge(resources:)
|
54
|
+
resources[@network_acl_id] = Resources::EC2.network_acl(
|
55
|
+
vpc: @vpc_id
|
56
|
+
)
|
57
|
+
resources[@subnet_network_acl_association_id] =
|
58
|
+
Resources::EC2.subnet_network_acl_association(
|
59
|
+
subnet: @subnet_id,
|
60
|
+
network_acl: @network_acl_id
|
61
|
+
)
|
62
|
+
_add_default_rules resources
|
63
|
+
_add_source_cidrs resources
|
64
|
+
end
|
65
|
+
# rubocop:enable Metrics/MethodLength
|
66
|
+
|
67
|
+
# rubocop:disable Metrics/MethodLength
|
68
|
+
def _add_default_rules(resources)
|
69
|
+
resources[@network_acl_entry_vpc_inbound_id] =
|
70
|
+
Resources::EC2.network_acl_entry(
|
71
|
+
network_acl: @network_acl_id,
|
72
|
+
cidr: @vpc_cidr,
|
73
|
+
egress: false,
|
74
|
+
protocol: -1,
|
75
|
+
action: 'allow',
|
76
|
+
icmp_code: -1,
|
77
|
+
icmp_type: -1,
|
78
|
+
number: 100
|
79
|
+
)
|
80
|
+
resources[@network_acl_entry_external_inbound_tcp_id] =
|
81
|
+
Resources::EC2.network_acl_entry(
|
82
|
+
network_acl: @network_acl_id,
|
83
|
+
cidr: '0.0.0.0/0',
|
84
|
+
egress: false,
|
85
|
+
protocol: 6,
|
86
|
+
action: 'allow',
|
87
|
+
start_port: EPHEMERAL_PORT_START,
|
88
|
+
end_port: EPHEMERAL_PORT_END,
|
89
|
+
number: 200
|
90
|
+
)
|
91
|
+
resources[@network_acl_entry_external_inbound_udp_id] =
|
92
|
+
Resources::EC2.network_acl_entry(
|
93
|
+
network_acl: @network_acl_id,
|
94
|
+
cidr: '0.0.0.0/0',
|
95
|
+
egress: false,
|
96
|
+
protocol: 17,
|
97
|
+
action: 'allow',
|
98
|
+
start_port: EPHEMERAL_PORT_START,
|
99
|
+
end_port: EPHEMERAL_PORT_END,
|
100
|
+
number: 300
|
101
|
+
)
|
102
|
+
resources[@network_acl_entry_outbound_id] =
|
103
|
+
Resources::EC2.network_acl_entry(
|
104
|
+
network_acl: @network_acl_id,
|
105
|
+
cidr: '0.0.0.0/0',
|
106
|
+
egress: true,
|
107
|
+
protocol: -1,
|
108
|
+
action: 'allow',
|
109
|
+
icmp_code: -1,
|
110
|
+
icmp_type: -1,
|
111
|
+
number: 400
|
112
|
+
)
|
113
|
+
end
|
114
|
+
# rubocop:enable Metrics/MethodLength
|
115
|
+
|
116
|
+
# rubocop:disable Metrics/MethodLength
|
117
|
+
def _add_source_cidrs(resources)
|
118
|
+
@source_cidrs.each_index do |index|
|
119
|
+
source_cidr = @source_cidrs[index]
|
120
|
+
resources[
|
121
|
+
"#{EXTERNAL_INBOUND_NETWORK_ACL_ENTRY_PREFIX}" \
|
122
|
+
"#{index}#{@subnet_guid}"
|
123
|
+
] = Resources::EC2.network_acl_entry(
|
124
|
+
network_acl: @network_acl_id,
|
125
|
+
cidr: source_cidr,
|
126
|
+
egress: false,
|
127
|
+
protocol: -1,
|
128
|
+
action: 'allow',
|
129
|
+
icmp_code: -1,
|
130
|
+
icmp_type: -1,
|
131
|
+
number: 500 + index
|
132
|
+
)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
# rubocop:enable Metrics/MethodLength
|
136
|
+
|
137
|
+
private(
|
138
|
+
:_add_default_rules,
|
139
|
+
:_add_source_cidrs
|
140
|
+
)
|
141
|
+
end
|
142
|
+
# rubocop:enable Metrics/ClassLength
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require_relative 'instance'
|
2
|
+
|
3
|
+
class Formatron
|
4
|
+
module CloudFormation
|
5
|
+
class Template
|
6
|
+
class VPC
|
7
|
+
class Subnet
|
8
|
+
# generates CloudFormation Bastion resources
|
9
|
+
class Bastion
|
10
|
+
# rubocop:disable Metrics/MethodLength
|
11
|
+
# rubocop:disable Metrics/ParameterLists
|
12
|
+
def initialize(
|
13
|
+
bastion:,
|
14
|
+
key_pair:,
|
15
|
+
availability_zone:,
|
16
|
+
subnet_guid:,
|
17
|
+
hosted_zone_name:,
|
18
|
+
vpc_guid:,
|
19
|
+
vpc_cidr:,
|
20
|
+
kms_key:,
|
21
|
+
private_hosted_zone_id:,
|
22
|
+
public_hosted_zone_id:,
|
23
|
+
bucket:,
|
24
|
+
name:,
|
25
|
+
target:
|
26
|
+
)
|
27
|
+
@bastion = bastion
|
28
|
+
_add_open_ports
|
29
|
+
@instance = Instance.new(
|
30
|
+
instance: bastion,
|
31
|
+
key_pair: key_pair,
|
32
|
+
availability_zone: availability_zone,
|
33
|
+
subnet_guid: subnet_guid,
|
34
|
+
hosted_zone_name: hosted_zone_name,
|
35
|
+
vpc_guid: vpc_guid,
|
36
|
+
vpc_cidr: vpc_cidr,
|
37
|
+
kms_key: kms_key,
|
38
|
+
private_hosted_zone_id: private_hosted_zone_id,
|
39
|
+
public_hosted_zone_id: public_hosted_zone_id,
|
40
|
+
bucket: bucket,
|
41
|
+
name: name,
|
42
|
+
target: target
|
43
|
+
)
|
44
|
+
end
|
45
|
+
# rubocop:enable Metrics/ParameterLists
|
46
|
+
# rubocop:enable Metrics/MethodLength
|
47
|
+
|
48
|
+
def _add_open_ports
|
49
|
+
@bastion.security_group do |security_group|
|
50
|
+
security_group.open_tcp_port 22
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def merge(resources:, outputs:)
|
55
|
+
@instance.merge resources: resources, outputs: outputs
|
56
|
+
end
|
57
|
+
|
58
|
+
private(
|
59
|
+
:_add_open_ports
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require_relative 'instance'
|
2
|
+
require 'formatron/s3/chef_server_cert'
|
3
|
+
require 'formatron/s3/chef_server_keys'
|
4
|
+
require 'formatron/cloud_formation/resources/iam'
|
5
|
+
|
6
|
+
class Formatron
|
7
|
+
module CloudFormation
|
8
|
+
class Template
|
9
|
+
class VPC
|
10
|
+
class Subnet
|
11
|
+
# generates CloudFormation Chef Server resources
|
12
|
+
# rubocop:disable Metrics/ClassLength
|
13
|
+
class ChefServer
|
14
|
+
USER_PREFIX = 'user'
|
15
|
+
ACCESS_KEY_PREFIX = 'accessKey'
|
16
|
+
|
17
|
+
# rubocop:disable Metrics/MethodLength
|
18
|
+
# rubocop:disable Metrics/ParameterLists
|
19
|
+
# rubocop:disable Metrics/AbcSize
|
20
|
+
def initialize(
|
21
|
+
chef_server:,
|
22
|
+
key_pair:,
|
23
|
+
availability_zone:,
|
24
|
+
subnet_guid:,
|
25
|
+
hosted_zone_name:,
|
26
|
+
vpc_guid:,
|
27
|
+
vpc_cidr:,
|
28
|
+
kms_key:,
|
29
|
+
private_hosted_zone_id:,
|
30
|
+
public_hosted_zone_id:,
|
31
|
+
bucket:,
|
32
|
+
name:,
|
33
|
+
target:
|
34
|
+
)
|
35
|
+
@chef_server = chef_server
|
36
|
+
@bucket = bucket
|
37
|
+
guid = @chef_server.guid
|
38
|
+
@ssl_cert_key = S3::ChefServerCert.cert_key(
|
39
|
+
name: name,
|
40
|
+
target: target,
|
41
|
+
guid: guid
|
42
|
+
)
|
43
|
+
@ssl_key_key = S3::ChefServerCert.key_key(
|
44
|
+
name: name,
|
45
|
+
target: target,
|
46
|
+
guid: guid
|
47
|
+
)
|
48
|
+
@user_pem_key = S3::ChefServerKeys.user_pem_key(
|
49
|
+
name: name,
|
50
|
+
target: target,
|
51
|
+
guid: guid
|
52
|
+
)
|
53
|
+
@organization_pem_key =
|
54
|
+
S3::ChefServerKeys.organization_pem_key(
|
55
|
+
name: name,
|
56
|
+
target: target,
|
57
|
+
guid: guid
|
58
|
+
)
|
59
|
+
@user_id = "#{USER_PREFIX}#{guid}"
|
60
|
+
@access_key_id = "#{ACCESS_KEY_PREFIX}#{guid}"
|
61
|
+
@kms_key = kms_key
|
62
|
+
@username = @chef_server.username
|
63
|
+
@password = @chef_server.password
|
64
|
+
@first_name = @chef_server.first_name
|
65
|
+
@last_name = @chef_server.last_name
|
66
|
+
@email = @chef_server.email
|
67
|
+
@version = @chef_server.version
|
68
|
+
@cookbooks_bucket = @chef_server.cookbooks_bucket
|
69
|
+
organization = @chef_server.organization
|
70
|
+
@organization_short_name = organization.short_name
|
71
|
+
@organization_full_name = organization.full_name
|
72
|
+
_set_default_instance_type
|
73
|
+
_add_ssl_cert_policy
|
74
|
+
_add_keys_policy
|
75
|
+
_add_open_ports
|
76
|
+
_add_setup_script
|
77
|
+
@instance = Instance.new(
|
78
|
+
instance: @chef_server,
|
79
|
+
key_pair: key_pair,
|
80
|
+
availability_zone: availability_zone,
|
81
|
+
subnet_guid: subnet_guid,
|
82
|
+
hosted_zone_name: hosted_zone_name,
|
83
|
+
vpc_guid: vpc_guid,
|
84
|
+
vpc_cidr: vpc_cidr,
|
85
|
+
kms_key: @kms_key,
|
86
|
+
private_hosted_zone_id: private_hosted_zone_id,
|
87
|
+
public_hosted_zone_id: public_hosted_zone_id,
|
88
|
+
bucket: @bucket,
|
89
|
+
name: name,
|
90
|
+
target: target
|
91
|
+
)
|
92
|
+
end
|
93
|
+
# rubocop:enable Metrics/AbcSize
|
94
|
+
# rubocop:enable Metrics/ParameterLists
|
95
|
+
# rubocop:enable Metrics/MethodLength
|
96
|
+
|
97
|
+
def _set_default_instance_type
|
98
|
+
@chef_server.instance_type(
|
99
|
+
't2.medium'
|
100
|
+
) if @chef_server.instance_type.nil?
|
101
|
+
end
|
102
|
+
|
103
|
+
def _add_ssl_cert_policy
|
104
|
+
@chef_server.policy do |policy|
|
105
|
+
policy.statement do |statement|
|
106
|
+
statement.action 's3:GetObject'
|
107
|
+
statement.resource "arn:aws:s3:::#{@bucket}/#{@ssl_cert_key}"
|
108
|
+
statement.resource "arn:aws:s3:::#{@bucket}/#{@ssl_key_key}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def _add_keys_policy
|
114
|
+
@chef_server.policy do |policy|
|
115
|
+
policy.statement do |statement|
|
116
|
+
statement.action 's3:PutObject'
|
117
|
+
statement.resource "arn:aws:s3:::#{@bucket}/#{@user_pem_key}"
|
118
|
+
statement.resource(
|
119
|
+
"arn:aws:s3:::#{@bucket}/#{@organization_pem_key}"
|
120
|
+
)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def _add_open_ports
|
126
|
+
@chef_server.security_group do |security_group|
|
127
|
+
security_group.open_tcp_port 80
|
128
|
+
security_group.open_tcp_port 443
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# rubocop:disable Metrics/MethodLength
|
133
|
+
def _add_setup_script
|
134
|
+
@chef_server.setup do |setup|
|
135
|
+
scripts = setup.script
|
136
|
+
scripts.unshift Scripts.chef_server(
|
137
|
+
username: @username,
|
138
|
+
first_name: @first_name,
|
139
|
+
last_name: @last_name,
|
140
|
+
email: @email,
|
141
|
+
password: @password,
|
142
|
+
organization_short_name: @organization_short_name,
|
143
|
+
organization_full_name: @organization_full_name,
|
144
|
+
bucket: @bucket,
|
145
|
+
user_pem_key: @user_pem_key,
|
146
|
+
organization_pem_key: @organization_pem_key,
|
147
|
+
kms_key: @kms_key,
|
148
|
+
chef_server_version: @version,
|
149
|
+
ssl_cert_key: @ssl_cert_key,
|
150
|
+
ssl_key_key: @ssl_key_key,
|
151
|
+
cookbooks_bucket: @cookbooks_bucket
|
152
|
+
)
|
153
|
+
setup.variable 'REGION' do |variable|
|
154
|
+
variable.value Template.ref('AWS::Region')
|
155
|
+
end
|
156
|
+
setup.variable 'ACCESS_KEY_ID' do |variable|
|
157
|
+
variable.value Template.ref(@access_key_id)
|
158
|
+
end
|
159
|
+
setup.variable 'SECRET_ACCESS_KEY' do |variable|
|
160
|
+
variable.value Template.get_attribute(
|
161
|
+
@access_key_id, 'SecretAccessKey'
|
162
|
+
)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
# rubocop:enable Metrics/MethodLength
|
167
|
+
|
168
|
+
def merge(resources:, outputs:)
|
169
|
+
_add_cookbooks_bucket_user resources
|
170
|
+
@instance.merge resources: resources, outputs: outputs
|
171
|
+
end
|
172
|
+
|
173
|
+
# rubocop:disable Metrics/MethodLength
|
174
|
+
def _add_cookbooks_bucket_user(resources)
|
175
|
+
resources[@user_id] = Resources::IAM.user(
|
176
|
+
policy_name: @user_id,
|
177
|
+
statements: [{
|
178
|
+
actions: %w(s3:PutObject s3:GetObject s3:DeleteObject),
|
179
|
+
resources: "arn:aws:s3:::#{@cookbooks_bucket}/*"
|
180
|
+
}, {
|
181
|
+
actions: %w(s3:ListBucket),
|
182
|
+
resources: "arn:aws:s3:::#{@cookbooks_bucket}"
|
183
|
+
}]
|
184
|
+
)
|
185
|
+
resources[@access_key_id] = Resources::IAM.access_key(
|
186
|
+
user_name: Template.ref(@user_id)
|
187
|
+
)
|
188
|
+
end
|
189
|
+
# rubocop:enable Metrics/MethodLength
|
190
|
+
|
191
|
+
private(
|
192
|
+
:_set_default_instance_type,
|
193
|
+
:_add_ssl_cert_policy,
|
194
|
+
:_add_keys_policy,
|
195
|
+
:_add_open_ports,
|
196
|
+
:_add_setup_script,
|
197
|
+
:_add_cookbooks_bucket_user
|
198
|
+
)
|
199
|
+
end
|
200
|
+
# rubocop:enable Metrics/ClassLength
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|