formatron 0.1.0

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.
Files changed (104) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +12 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +3 -0
  6. data/.simplecov +7 -0
  7. data/.travis.yml +17 -0
  8. data/CODE_OF_CONDUCT.md +13 -0
  9. data/Gemfile +6 -0
  10. data/Guardfile +16 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +93 -0
  13. data/Rakefile +16 -0
  14. data/bin/console +14 -0
  15. data/bin/setup +7 -0
  16. data/exe/formatron +20 -0
  17. data/formatron.gemspec +52 -0
  18. data/lib/formatron.rb +357 -0
  19. data/lib/formatron/aws.rb +197 -0
  20. data/lib/formatron/chef.rb +156 -0
  21. data/lib/formatron/chef/berkshelf.rb +55 -0
  22. data/lib/formatron/chef/keys.rb +48 -0
  23. data/lib/formatron/chef/knife.rb +169 -0
  24. data/lib/formatron/chef_clients.rb +73 -0
  25. data/lib/formatron/cli.rb +33 -0
  26. data/lib/formatron/cli/completion.rb +26 -0
  27. data/lib/formatron/cli/deploy.rb +57 -0
  28. data/lib/formatron/cli/destroy.rb +57 -0
  29. data/lib/formatron/cli/generators/bootstrap.rb +250 -0
  30. data/lib/formatron/cli/generators/credentials.rb +100 -0
  31. data/lib/formatron/cli/generators/instance.rb +118 -0
  32. data/lib/formatron/cli/provision.rb +59 -0
  33. data/lib/formatron/cloud_formation.rb +54 -0
  34. data/lib/formatron/cloud_formation/resources/cloud_formation.rb +27 -0
  35. data/lib/formatron/cloud_formation/resources/ec2.rb +336 -0
  36. data/lib/formatron/cloud_formation/resources/iam.rb +94 -0
  37. data/lib/formatron/cloud_formation/resources/route53.rb +54 -0
  38. data/lib/formatron/cloud_formation/scripts.rb +128 -0
  39. data/lib/formatron/cloud_formation/template.rb +114 -0
  40. data/lib/formatron/cloud_formation/template/parameters.rb +20 -0
  41. data/lib/formatron/cloud_formation/template/vpc.rb +181 -0
  42. data/lib/formatron/cloud_formation/template/vpc/subnet.rb +187 -0
  43. data/lib/formatron/cloud_formation/template/vpc/subnet/acl.rb +147 -0
  44. data/lib/formatron/cloud_formation/template/vpc/subnet/bastion.rb +66 -0
  45. data/lib/formatron/cloud_formation/template/vpc/subnet/chef_server.rb +205 -0
  46. data/lib/formatron/cloud_formation/template/vpc/subnet/instance.rb +162 -0
  47. data/lib/formatron/cloud_formation/template/vpc/subnet/instance/policy.rb +74 -0
  48. data/lib/formatron/cloud_formation/template/vpc/subnet/instance/security_group.rb +117 -0
  49. data/lib/formatron/cloud_formation/template/vpc/subnet/instance/setup.rb +68 -0
  50. data/lib/formatron/cloud_formation/template/vpc/subnet/nat.rb +94 -0
  51. data/lib/formatron/completion.rb +26 -0
  52. data/lib/formatron/completion/completion.sh.erb +35 -0
  53. data/lib/formatron/config.rb +31 -0
  54. data/lib/formatron/config/reader.rb +29 -0
  55. data/lib/formatron/dsl.rb +15 -0
  56. data/lib/formatron/dsl/formatron.rb +25 -0
  57. data/lib/formatron/dsl/formatron/global.rb +19 -0
  58. data/lib/formatron/dsl/formatron/global/ec2.rb +17 -0
  59. data/lib/formatron/dsl/formatron/vpc.rb +17 -0
  60. data/lib/formatron/dsl/formatron/vpc/subnet.rb +27 -0
  61. data/lib/formatron/dsl/formatron/vpc/subnet/acl.rb +18 -0
  62. data/lib/formatron/dsl/formatron/vpc/subnet/chef_server.rb +32 -0
  63. data/lib/formatron/dsl/formatron/vpc/subnet/chef_server/organization.rb +22 -0
  64. data/lib/formatron/dsl/formatron/vpc/subnet/instance.rb +29 -0
  65. data/lib/formatron/dsl/formatron/vpc/subnet/instance/chef.rb +22 -0
  66. data/lib/formatron/dsl/formatron/vpc/subnet/instance/policy.rb +21 -0
  67. data/lib/formatron/dsl/formatron/vpc/subnet/instance/policy/statement.rb +23 -0
  68. data/lib/formatron/dsl/formatron/vpc/subnet/instance/security_group.rb +21 -0
  69. data/lib/formatron/dsl/formatron/vpc/subnet/instance/setup.rb +22 -0
  70. data/lib/formatron/dsl/formatron/vpc/subnet/instance/setup/variable.rb +23 -0
  71. data/lib/formatron/external.rb +61 -0
  72. data/lib/formatron/external/dsl.rb +171 -0
  73. data/lib/formatron/external/outputs.rb +25 -0
  74. data/lib/formatron/generators/bootstrap.rb +90 -0
  75. data/lib/formatron/generators/bootstrap/config.rb +62 -0
  76. data/lib/formatron/generators/bootstrap/ec2.rb +17 -0
  77. data/lib/formatron/generators/bootstrap/formatronfile.rb +52 -0
  78. data/lib/formatron/generators/bootstrap/formatronfile/Formatronfile.erb +79 -0
  79. data/lib/formatron/generators/bootstrap/ssl.rb +35 -0
  80. data/lib/formatron/generators/credentials.rb +17 -0
  81. data/lib/formatron/generators/instance.rb +64 -0
  82. data/lib/formatron/generators/instance/config.rb +47 -0
  83. data/lib/formatron/generators/instance/formatronfile.rb +47 -0
  84. data/lib/formatron/generators/instance/formatronfile/Formatronfile.erb +16 -0
  85. data/lib/formatron/generators/util.rb +14 -0
  86. data/lib/formatron/generators/util/cookbook.rb +65 -0
  87. data/lib/formatron/generators/util/gitignore.rb +16 -0
  88. data/lib/formatron/generators/util/readme.rb +18 -0
  89. data/lib/formatron/logger.rb +8 -0
  90. data/lib/formatron/s3/chef_server_cert.rb +85 -0
  91. data/lib/formatron/s3/chef_server_keys.rb +103 -0
  92. data/lib/formatron/s3/cloud_formation_template.rb +61 -0
  93. data/lib/formatron/s3/configuration.rb +58 -0
  94. data/lib/formatron/s3/path.rb +30 -0
  95. data/lib/formatron/util/dsl.rb +107 -0
  96. data/lib/formatron/util/shell.rb +20 -0
  97. data/lib/formatron/util/vpc.rb +15 -0
  98. data/lib/formatron/version.rb +4 -0
  99. data/support/cloudformation_describe_stacks_response.rb +36 -0
  100. data/support/dsl_test.rb +123 -0
  101. data/support/route53_get_hosted_zone_response.rb +21 -0
  102. data/support/s3_get_object_response.rb +21 -0
  103. data/support/template_test.rb +41 -0
  104. 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