terraforming 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 732437685979fbd266b3f855c81ffb184be35856
4
- data.tar.gz: 5f3ef26d21cab520886d5a4ebff23e2af13d5b03
3
+ metadata.gz: 3a6da3b6025e72dbde110224ba597ae281004e64
4
+ data.tar.gz: a8ab14e29325070270895d2bd7d9dfc1f456bb64
5
5
  SHA512:
6
- metadata.gz: c564d548f74b3650cf1509388cafd66bc831e705f16c881f05aa8cf5507aa93e35106f15eb5b0f74f77cbacae9f342508751417219e3ae009c94339806d6cd72
7
- data.tar.gz: e451f2a2619e7cad7658fbfc33155fe948edb7e583fb2f4cb914b3b16d9a4dd6a444b98d08ec2301a56cb28bb876aebd2c454bb5797cbbfff864b9fa2e8d69f6
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.block_device_mappings.length.to_s,
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.root_device_name ? "1" : "0",
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
- "subnet_id"=> instance.subnet_id,
41
- "tenancy"=> instance.placement.tenancy
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
@@ -77,7 +77,7 @@ module Terraforming
77
77
  end
78
78
 
79
79
  def module_name_of(record)
80
- normalize_module_name(name_of(record.name))
80
+ normalize_module_name(name_of(record.name) + "-" + record.type)
81
81
  end
82
82
 
83
83
  def zone_id_of(hosted_zone)
@@ -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
- security_groups = <%= instance.security_groups.map { |sg| sg.group_id }.inspect %>
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.block_device_mappings.each do |block_device| -%>
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 = "<%= block_device.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 -%>
@@ -1,3 +1,3 @@
1
1
  module Terraforming
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
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.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-14 00:00:00.000000000 Z
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.7
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: