terraforming 0.1.1 → 0.1.2
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/CHANGELOG.md +8 -0
- data/README.md +3 -0
- data/lib/terraforming/resource/ec2.rb +53 -7
- data/lib/terraforming/resource/elb.rb +111 -4
- data/lib/terraforming/resource/route53_record.rb +1 -1
- data/lib/terraforming/template/tf/ec2.erb +22 -3
- data/lib/terraforming/template/tf/elb.erb +6 -0
- data/lib/terraforming/version.rb +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a6da3b6025e72dbde110224ba597ae281004e64
|
4
|
+
data.tar.gz: a8ab14e29325070270895d2bd7d9dfc1f456bb64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7611a6cc8554f7661ff3c579306becffc4da9ed077e8087b7c1e68e57b14eed25cbdb7d1e8d342fd4c547daf1c1788ed9ec30b22c4eba19c46d66458d8bfbc67
|
7
|
+
data.tar.gz: 8435e655557d88686a783ae7045a0ecd8a5deb10514be0645372caf92eb7855f49024b10294be8faeb78caaf6d49be1f18b39009c6d2997611fcfd205de4c1ec
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
# [v0.1.2](https://github.com/dtan4/terraforming/releases/tag/v0.1.2) (2015-07-30)
|
2
|
+
|
3
|
+
## Fixed
|
4
|
+
|
5
|
+
- Generate correct tf and tfstate of EC2 #94, #102
|
6
|
+
- Handle multiple Route53 record types #99 (thanks @nicgrayson)
|
7
|
+
- Generate correct tfstate of ELB #91 (thanks @grosendorf)
|
8
|
+
|
1
9
|
# [v0.1.1](https://github.com/dtan4/terraforming/releases/tag/v0.1.1) (2015-07-14)
|
2
10
|
|
3
11
|
### Resource
|
data/README.md
CHANGED
@@ -60,8 +60,11 @@ Commands:
|
|
60
60
|
terraforming dbsg # Database Security Group
|
61
61
|
terraforming dbsn # Database Subnet Group
|
62
62
|
terraforming ec2 # EC2
|
63
|
+
terraforming ecc # ElastiCache Cluster
|
64
|
+
terraforming ecsn # ElastiCache Subnet Group
|
63
65
|
terraforming elb # ELB
|
64
66
|
terraforming iamg # IAM Group
|
67
|
+
terraforming iamgm # IAM Group Membership
|
65
68
|
terraforming iamgp # IAM Group Policy
|
66
69
|
terraforming iamip # IAM Instance Profile
|
67
70
|
terraforming iamp # IAM Policy
|
@@ -21,25 +21,31 @@ module Terraforming
|
|
21
21
|
|
22
22
|
def tfstate(tfstate_base)
|
23
23
|
resources = instances.inject({}) do |result, instance|
|
24
|
+
in_vpc = in_vpc?(instance)
|
25
|
+
block_devices = block_devices_of(instance)
|
26
|
+
|
24
27
|
attributes = {
|
25
28
|
"ami"=> instance.image_id,
|
26
29
|
"associate_public_ip_address"=> "true",
|
27
30
|
"availability_zone"=> instance.placement.availability_zone,
|
28
|
-
"ebs_block_device.#"=> instance.
|
31
|
+
"ebs_block_device.#"=> ebs_block_devices_in(block_devices, instance).length.to_s,
|
29
32
|
"ebs_optimized"=> instance.ebs_optimized.to_s,
|
30
|
-
"ephemeral_block_device.#"=> "0",
|
33
|
+
"ephemeral_block_device.#" => "0", # Terraform 0.6.1 cannot fetch this field from AWS
|
31
34
|
"id"=> instance.instance_id,
|
32
35
|
"instance_type"=> instance.instance_type,
|
33
36
|
"private_dns"=> instance.private_dns_name,
|
34
37
|
"private_ip"=> instance.private_ip_address,
|
35
38
|
"public_dns"=> instance.public_dns_name,
|
36
39
|
"public_ip"=> instance.public_ip_address,
|
37
|
-
"root_block_device.#"=> instance.
|
38
|
-
"security_groups.#"=> instance.security_groups.length.to_s,
|
40
|
+
"root_block_device.#"=> root_block_devices_in(block_devices, instance).length.to_s,
|
41
|
+
"security_groups.#"=> in_vpc ? "0" : instance.security_groups.length.to_s,
|
39
42
|
"source_dest_check"=> instance.source_dest_check.to_s,
|
40
|
-
"
|
41
|
-
"
|
43
|
+
"tenancy"=> instance.placement.tenancy,
|
44
|
+
"vpc_security_group_ids.#"=> in_vpc ? instance.security_groups.length.to_s : "0",
|
42
45
|
}
|
46
|
+
|
47
|
+
attributes["subnet_id"] = instance.subnet_id if in_vpc?(instance)
|
48
|
+
|
43
49
|
result["aws_instance.#{module_name_of(instance)}"] = {
|
44
50
|
"type" => "aws_instance",
|
45
51
|
"primary" => {
|
@@ -59,13 +65,53 @@ module Terraforming
|
|
59
65
|
|
60
66
|
private
|
61
67
|
|
68
|
+
def block_device_ids_of(instance)
|
69
|
+
instance.block_device_mappings.map { |bdm| bdm.ebs.volume_id }
|
70
|
+
end
|
71
|
+
|
72
|
+
def block_devices_of(instance)
|
73
|
+
@client.describe_volumes(volume_ids: block_device_ids_of(instance)).volumes
|
74
|
+
end
|
75
|
+
|
76
|
+
def block_device_mapping_of(instance, volume_id)
|
77
|
+
instance.block_device_mappings.select { |bdm| bdm.ebs.volume_id == volume_id }[0]
|
78
|
+
end
|
79
|
+
|
80
|
+
def ebs_block_devices_in(block_devices, instance)
|
81
|
+
block_devices.reject do |bd|
|
82
|
+
root_block_device?(block_device_mapping_of(instance, bd.volume_id), instance)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
# NOTE(dtan4):
|
88
|
+
# Original logic is here:
|
89
|
+
# https://github.com/hashicorp/terraform/blob/281e4d3e67f66daab9cdb1f7c8b6f602d949e5ee/builtin/providers/aws/resource_aws_instance.go#L481-L501
|
90
|
+
#
|
91
|
+
def in_vpc?(instance)
|
92
|
+
vpc_security_groups_of(instance).length > 0 ||
|
93
|
+
(instance.subnet_id && instance.subnet_id != "" && instance.security_groups.length == 0)
|
94
|
+
end
|
95
|
+
|
62
96
|
def instances
|
63
|
-
@client.describe_instances.reservations.map(&:instances).flatten
|
97
|
+
@client.describe_instances.reservations.map(&:instances).flatten.reject { |instance| instance.state.name == "terminated" }
|
64
98
|
end
|
65
99
|
|
66
100
|
def module_name_of(instance)
|
67
101
|
normalize_module_name(name_from_tag(instance, instance.instance_id))
|
68
102
|
end
|
103
|
+
|
104
|
+
def root_block_device?(block_device_mapping, instance)
|
105
|
+
block_device_mapping.device_name == instance.root_device_name
|
106
|
+
end
|
107
|
+
|
108
|
+
def root_block_devices_in(block_devices, instance)
|
109
|
+
block_devices.select { |bd| root_block_device?(block_device_mapping_of(instance, bd.volume_id), instance) }
|
110
|
+
end
|
111
|
+
|
112
|
+
def vpc_security_groups_of(instance)
|
113
|
+
instance.security_groups.select { |security_group| /\Asg-/ =~ security_group.group_id }
|
114
|
+
end
|
69
115
|
end
|
70
116
|
end
|
71
117
|
end
|
@@ -28,16 +28,21 @@ module Terraforming
|
|
28
28
|
"connection_draining_timeout" => load_balancer_attributes.connection_draining.timeout.to_s,
|
29
29
|
"cross_zone_load_balancing" => load_balancer_attributes.cross_zone_load_balancing.enabled.to_s,
|
30
30
|
"dns_name" => load_balancer.dns_name,
|
31
|
-
"health_check.#" => "1",
|
32
31
|
"id" => load_balancer.load_balancer_name,
|
33
32
|
"idle_timeout" => load_balancer_attributes.connection_settings.idle_timeout.to_s,
|
34
33
|
"instances.#" => load_balancer.instances.length.to_s,
|
35
|
-
"listener.#" => load_balancer.listener_descriptions.length.to_s,
|
36
34
|
"name" => load_balancer.load_balancer_name,
|
37
|
-
"security_groups.#" => load_balancer.security_groups.length.to_s,
|
38
35
|
"source_security_group" => load_balancer.source_security_group.group_name,
|
39
|
-
"subnets.#" => load_balancer.subnets.length.to_s,
|
40
36
|
}
|
37
|
+
|
38
|
+
attributes.merge!(healthcheck_attributes_of(load_balancer))
|
39
|
+
attributes.merge!(listeners_attributes_of(load_balancer))
|
40
|
+
attributes.merge!(sg_attributes_of(load_balancer))
|
41
|
+
attributes.merge!(subnets_attributes_of(load_balancer))
|
42
|
+
attributes.merge!(instances_attributes_of(load_balancer))
|
43
|
+
attributes.merge!(tags_attributes_of(load_balancer))
|
44
|
+
|
45
|
+
|
41
46
|
result["aws_elb.#{module_name_of(load_balancer)}"] = {
|
42
47
|
"type" => "aws_elb",
|
43
48
|
"primary" => {
|
@@ -52,6 +57,108 @@ module Terraforming
|
|
52
57
|
generate_tfstate(resources, tfstate_base)
|
53
58
|
end
|
54
59
|
|
60
|
+
def healthcheck_attributes_of(elb)
|
61
|
+
hashcode = healthcheck_hashcode_of(elb.health_check)
|
62
|
+
attributes = {
|
63
|
+
# Now each ELB supports one heatlhcheck
|
64
|
+
"health_check.#" => "1",
|
65
|
+
"health_check.#{hashcode}.healthy_threshold" => elb.health_check.healthy_threshold.to_s,
|
66
|
+
"health_check.#{hashcode}.interval" => elb.health_check.interval.to_s,
|
67
|
+
"health_check.#{hashcode}.target" => elb.health_check.target,
|
68
|
+
"health_check.#{hashcode}.timeout" => elb.health_check.timeout.to_s,
|
69
|
+
"health_check.#{hashcode}.unhealthy_threshold" => elb.health_check.unhealthy_threshold.to_s
|
70
|
+
}
|
71
|
+
|
72
|
+
attributes
|
73
|
+
end
|
74
|
+
|
75
|
+
def healthcheck_hashcode_of(health_check)
|
76
|
+
string =
|
77
|
+
"#{health_check.healthy_threshold}-" <<
|
78
|
+
"#{health_check.unhealthy_threshold}-" <<
|
79
|
+
"#{health_check.target}-" <<
|
80
|
+
"#{health_check.interval}-" <<
|
81
|
+
"#{health_check.timeout}-"
|
82
|
+
|
83
|
+
Zlib.crc32(string)
|
84
|
+
end
|
85
|
+
|
86
|
+
def tags_attributes_of(elb)
|
87
|
+
tags = @client.describe_tags(load_balancer_names: [elb.load_balancer_name]).tag_descriptions.first.tags
|
88
|
+
attributes = {"tags.#" => tags.length.to_s}
|
89
|
+
|
90
|
+
tags.each do |tag|
|
91
|
+
attributes["tags.#{tag.key}"] = tag.value
|
92
|
+
end
|
93
|
+
|
94
|
+
attributes
|
95
|
+
end
|
96
|
+
|
97
|
+
def instances_attributes_of(elb)
|
98
|
+
attributes = {"instances.#" => elb.instances.length.to_s}
|
99
|
+
|
100
|
+
elb.instances.each do |instance|
|
101
|
+
attributes["instances.#{Zlib.crc32(instance.instance_id)}"] = instance.instance_id
|
102
|
+
end
|
103
|
+
|
104
|
+
attributes
|
105
|
+
end
|
106
|
+
|
107
|
+
def subnets_attributes_of(elb)
|
108
|
+
attributes = {"subnets.#" => elb.subnets.length.to_s}
|
109
|
+
|
110
|
+
elb.subnets.each do |subnet_id|
|
111
|
+
attributes["subnets.#{Zlib.crc32(subnet_id)}"] = subnet_id
|
112
|
+
end
|
113
|
+
|
114
|
+
attributes
|
115
|
+
end
|
116
|
+
|
117
|
+
def sg_attributes_of(elb)
|
118
|
+
attributes = {"security_groups.#" => elb.security_groups.length.to_s}
|
119
|
+
|
120
|
+
elb.security_groups.each do |sg_id|
|
121
|
+
attributes["security_groups.#{Zlib.crc32(sg_id)}"] = sg_id
|
122
|
+
end
|
123
|
+
|
124
|
+
attributes
|
125
|
+
end
|
126
|
+
|
127
|
+
def listeners_attributes_of(elb)
|
128
|
+
attributes = {"listener.#" => elb.listener_descriptions.length.to_s}
|
129
|
+
|
130
|
+
elb.listener_descriptions.each do |listener_description|
|
131
|
+
attributes.merge!(listener_attributes_of(listener_description.listener))
|
132
|
+
end
|
133
|
+
|
134
|
+
attributes
|
135
|
+
end
|
136
|
+
|
137
|
+
def listener_attributes_of(listener)
|
138
|
+
hashcode = listener_hashcode_of(listener)
|
139
|
+
|
140
|
+
attributes = {
|
141
|
+
"listener.#{hashcode}.instance_port" => listener.instance_port.to_s,
|
142
|
+
"listener.#{hashcode}.instance_protocol" => listener.instance_protocol.downcase,
|
143
|
+
"listener.#{hashcode}.lb_port" => listener.load_balancer_port.to_s,
|
144
|
+
"listener.#{hashcode}.lb_protocol" => listener.protocol.downcase,
|
145
|
+
"listener.#{hashcode}.ssl_certificate_id" => listener.ssl_certificate_id
|
146
|
+
}
|
147
|
+
|
148
|
+
attributes
|
149
|
+
end
|
150
|
+
|
151
|
+
def listener_hashcode_of(listener)
|
152
|
+
string =
|
153
|
+
"#{listener.instance_port}-" <<
|
154
|
+
"#{listener.instance_protocol.downcase}-" <<
|
155
|
+
"#{listener.load_balancer_port}-" <<
|
156
|
+
"#{listener.protocol.downcase}-" <<
|
157
|
+
"#{listener.ssl_certificate_id}-"
|
158
|
+
|
159
|
+
Zlib.crc32(string)
|
160
|
+
end
|
161
|
+
|
55
162
|
def load_balancers
|
56
163
|
@client.describe_load_balancers.load_balancer_descriptions
|
57
164
|
end
|
@@ -5,16 +5,35 @@ resource "aws_instance" "<%= module_name_of(instance) %>" {
|
|
5
5
|
ebs_optimized = <%= instance.ebs_optimized %>
|
6
6
|
instance_type = "<%= instance.instance_type %>"
|
7
7
|
key_name = "<%= instance.key_name %>"
|
8
|
-
|
8
|
+
<%- if in_vpc?(instance) -%>
|
9
9
|
subnet_id = "<%= instance.subnet_id %>"
|
10
|
+
vpc_security_group_ids = <%= instance.security_groups.map { |sg| sg.group_id }.inspect %>
|
11
|
+
<%- else -%>
|
12
|
+
security_groups = <%= instance.security_groups.map { |sg| sg.group_name }.inspect %>
|
13
|
+
<%- end -%>
|
10
14
|
associate_public_ip_address = true
|
11
15
|
private_ip = "<%= instance.private_ip_address %>"
|
12
16
|
source_dest_check = <%= instance.source_dest_check %>
|
13
17
|
|
14
|
-
<% instance.
|
18
|
+
<% block_devices_of(instance).each do |block_device| -%>
|
19
|
+
<%- mapping = block_device_mapping_of(instance, block_device.volume_id) -%>
|
20
|
+
<%- if root_block_device?(mapping, instance) -%>
|
21
|
+
root_block_device {
|
22
|
+
volume_type = "<%= block_device.volume_type %>"
|
23
|
+
volume_size = <%= block_device.size %>
|
24
|
+
iops = <%= block_device.iops %>
|
25
|
+
delete_on_termination = <%= mapping.ebs.delete_on_termination %>
|
26
|
+
}
|
27
|
+
<%- else -%>
|
15
28
|
ebs_block_device {
|
16
|
-
device_name
|
29
|
+
device_name = "<%= mapping.device_name %>"
|
30
|
+
snapshot_id = "<%= block_device.snapshot_id %>"
|
31
|
+
volume_type = "<%= block_device.volume_type %>"
|
32
|
+
volume_size = <%= block_device.size %>
|
33
|
+
iops = <%= block_device.iops %>
|
34
|
+
delete_on_termination = <%= mapping.ebs.delete_on_termination %>
|
17
35
|
}
|
36
|
+
<% end -%>
|
18
37
|
|
19
38
|
<% end -%>
|
20
39
|
tags {
|
@@ -31,6 +31,12 @@ resource "aws_elb" "<%= module_name_of(load_balancer) %>" {
|
|
31
31
|
target = "<%= load_balancer.health_check.target %>"
|
32
32
|
timeout = <%= load_balancer.health_check.timeout %>
|
33
33
|
}
|
34
|
+
|
35
|
+
tags {
|
36
|
+
<% @client.describe_tags(load_balancer_names: [load_balancer.load_balancer_name]).tag_descriptions.first.tags.each do |tag| -%>
|
37
|
+
<%= tag.key %> = "<%= tag.value %>"
|
38
|
+
<% end -%>
|
39
|
+
}
|
34
40
|
}
|
35
41
|
|
36
42
|
<% end -%>
|
data/lib/terraforming/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: terraforming
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daisuke Fujita
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-07-
|
11
|
+
date: 2015-07-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|
@@ -258,9 +258,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
258
258
|
version: '0'
|
259
259
|
requirements: []
|
260
260
|
rubyforge_project:
|
261
|
-
rubygems_version: 2.4.
|
261
|
+
rubygems_version: 2.4.5
|
262
262
|
signing_key:
|
263
263
|
specification_version: 4
|
264
264
|
summary: Export existing AWS resources to Terraform style (tf, tfstate)
|
265
265
|
test_files: []
|
266
|
-
has_rdoc:
|