formatron 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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