geoengineer 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +5 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +5 -5
  5. data/lib/geoengineer/cli/geo_cli.rb +4 -5
  6. data/lib/geoengineer/cli/status_command.rb +7 -1
  7. data/lib/geoengineer/environment.rb +53 -51
  8. data/lib/geoengineer/project.rb +5 -24
  9. data/lib/geoengineer/resource.rb +89 -20
  10. data/lib/geoengineer/resources/aws_customer_gateway.rb +23 -0
  11. data/lib/geoengineer/resources/aws_eip.rb +43 -0
  12. data/lib/geoengineer/resources/aws_iam_group.rb +26 -0
  13. data/lib/geoengineer/resources/aws_iam_group_membership.rb +50 -0
  14. data/lib/geoengineer/resources/aws_iam_policy.rb +12 -4
  15. data/lib/geoengineer/resources/aws_iam_policy_attachment.rb +95 -0
  16. data/lib/geoengineer/resources/aws_iam_role.rb +45 -0
  17. data/lib/geoengineer/resources/aws_instance.rb +7 -4
  18. data/lib/geoengineer/resources/aws_internet_gateway.rb +23 -0
  19. data/lib/geoengineer/resources/aws_lambda_alias.rb +50 -0
  20. data/lib/geoengineer/resources/aws_lambda_event_source_mapping.rb +47 -0
  21. data/lib/geoengineer/resources/aws_lambda_function.rb +30 -0
  22. data/lib/geoengineer/resources/aws_lambda_permission.rb +74 -0
  23. data/lib/geoengineer/resources/aws_main_route_table_association.rb +51 -0
  24. data/lib/geoengineer/resources/aws_nat_gateway.rb +29 -0
  25. data/lib/geoengineer/resources/aws_network_acl.rb +38 -0
  26. data/lib/geoengineer/resources/aws_network_acl_rule.rb +50 -0
  27. data/lib/geoengineer/resources/aws_route.rb +47 -0
  28. data/lib/geoengineer/resources/aws_route53_record.rb +4 -0
  29. data/lib/geoengineer/resources/aws_route_table.rb +26 -0
  30. data/lib/geoengineer/resources/aws_route_table_association.rb +45 -0
  31. data/lib/geoengineer/resources/aws_security_group.rb +8 -5
  32. data/lib/geoengineer/resources/aws_subnet.rb +24 -0
  33. data/lib/geoengineer/resources/aws_vpc.rb +24 -0
  34. data/lib/geoengineer/resources/aws_vpc_dhcp_options.rb +29 -0
  35. data/lib/geoengineer/resources/aws_vpc_dhcp_options_association.rb +40 -0
  36. data/lib/geoengineer/resources/aws_vpc_endpoint.rb +26 -0
  37. data/lib/geoengineer/resources/aws_vpc_peering_connection.rb +29 -0
  38. data/lib/geoengineer/resources/aws_vpn_connection.rb +23 -0
  39. data/lib/geoengineer/resources/aws_vpn_connection_route.rb +35 -0
  40. data/lib/geoengineer/resources/aws_vpn_gateway.rb +22 -0
  41. data/lib/geoengineer/resources/aws_vpn_gateway_attachment.rb +41 -0
  42. data/lib/geoengineer/template.rb +20 -4
  43. data/lib/geoengineer/utils/aws_clients.rb +4 -0
  44. data/lib/geoengineer/utils/crc32.rb +61 -0
  45. data/lib/geoengineer/utils/has_attributes.rb +25 -11
  46. data/lib/geoengineer/utils/has_projects.rb +21 -0
  47. data/lib/geoengineer/utils/has_resources.rb +17 -4
  48. data/lib/geoengineer/utils/has_templates.rb +31 -0
  49. data/lib/geoengineer/utils/has_validations.rb +18 -3
  50. data/lib/geoengineer/version.rb +1 -1
  51. data/spec/environment_spec.rb +40 -19
  52. data/spec/project_spec.rb +2 -2
  53. data/spec/resource_spec.rb +87 -6
  54. data/spec/resources/aws_customer_gateway_spec.rb +24 -0
  55. data/spec/resources/aws_eip_spec.rb +29 -0
  56. data/spec/resources/aws_iam_group_membership_spec.rb +83 -0
  57. data/spec/resources/aws_iam_group_spec.rb +43 -0
  58. data/spec/resources/aws_iam_policy_attachment_spec.rb +80 -0
  59. data/spec/resources/{aws_iam_policy.rb → aws_iam_policy_spec.rb} +6 -5
  60. data/spec/resources/aws_iam_role_spec.rb +45 -0
  61. data/spec/resources/aws_internet_gateway_spec.rb +24 -0
  62. data/spec/resources/aws_lambda_alias_spec.rb +39 -0
  63. data/spec/resources/aws_lambda_event_source_mapping_spec.rb +53 -0
  64. data/spec/resources/aws_lambda_function_spec.rb +29 -0
  65. data/spec/resources/aws_lambda_permission_spec.rb +90 -0
  66. data/spec/resources/aws_main_route_table_association_spec.rb +57 -0
  67. data/spec/resources/aws_nat_gateway_spec.rb +31 -0
  68. data/spec/resources/aws_network_acl_rule_spec.rb +73 -0
  69. data/spec/resources/aws_network_acl_spec.rb +31 -0
  70. data/spec/resources/aws_route53_record_spec.rb +5 -0
  71. data/spec/resources/aws_route_spec.rb +47 -0
  72. data/spec/resources/aws_route_table_association_spec.rb +47 -0
  73. data/spec/resources/aws_route_table_spec.rb +24 -0
  74. data/spec/resources/aws_security_group_spec.rb +36 -2
  75. data/spec/resources/aws_subnet_spec.rb +24 -0
  76. data/spec/resources/aws_vpc_dhcp_options_association_spec.rb +43 -0
  77. data/spec/resources/aws_vpc_dhcp_options_spec.rb +24 -0
  78. data/spec/resources/aws_vpc_endpoint_spec.rb +41 -0
  79. data/spec/resources/aws_vpc_peering_connection_spec.rb +33 -0
  80. data/spec/resources/aws_vpc_spec.rb +24 -0
  81. data/spec/resources/aws_vpn_connection_route_spec.rb +43 -0
  82. data/spec/resources/aws_vpn_connection_spec.rb +41 -0
  83. data/spec/resources/aws_vpn_gateway_attachment_spec.rb +41 -0
  84. data/spec/resources/aws_vpn_gateway_spec.rb +39 -0
  85. data/spec/spec_helper.rb +3 -1
  86. data/spec/utils/crc32_spec.rb +14 -0
  87. data/spec/utils/has_attributes_spec.rb +22 -0
  88. data/spec/utils/has_resources_spec.rb +4 -0
  89. data/spec/utils/has_validations_spec.rb +45 -0
  90. metadata +117 -6
  91. metadata.gz.sig +1 -0
@@ -0,0 +1,30 @@
1
+ ########################################################################
2
+ # AwsLambdaFunction is the +aws_lambda_function+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/lambda_function.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsLambdaFunction < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:function_name, :handler, :role]) }
8
+ validate -> {
9
+ if self.vpc_config
10
+ validate_subresource_required_attributes(:vpc_config, [:subnet_ids, :security_group_ids])
11
+ end
12
+ }
13
+ validate -> {
14
+ if self.filename && (self.s3_bucket || self.s3_key || self.s3_object_version)
15
+ ["Can only define filename OR S3 config, not both"]
16
+ end
17
+ }
18
+
19
+ after :initialize, -> { _terraform_id -> { function_name } }
20
+
21
+ def support_tags?
22
+ false
23
+ end
24
+
25
+ def self._fetch_remote_resources
26
+ AwsClients.lambda.list_functions['functions'].map(&:to_h).map do |function|
27
+ function.merge({ _terraform_id: function[:function_name] })
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,74 @@
1
+ ########################################################################
2
+ # AwsLambdaPermission is the +aws_lambda_function+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/lambda_permission.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsLambdaPermission < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:action, :function_name, :principal, :statement_id]) }
8
+
9
+ after :initialize, -> { _terraform_id -> { statement_id } }
10
+
11
+ def support_tags?
12
+ false
13
+ end
14
+
15
+ def self._fetch_functions
16
+ AwsClients
17
+ .lambda
18
+ .list_functions['functions']
19
+ .map(&:to_h)
20
+ end
21
+
22
+ def self._fetch_policy(function)
23
+ policy = AwsClients.lambda.get_policy({ function_name: function[:function_name] })&.policy
24
+ parsed = _parse_policy(policy) if policy
25
+ function.merge({ policy: parsed }) if parsed
26
+ end
27
+
28
+ def self._parse_policy(policy)
29
+ _deep_symbolize_keys(JSON.parse(policy))
30
+ rescue JSON::ParserError
31
+ nil
32
+ end
33
+
34
+ def self._deep_symbolize_keys(obj)
35
+ if obj.is_a?(Hash)
36
+ obj.each_with_object({}) do |(key, value), hash|
37
+ hash[key.to_sym] = _deep_symbolize_keys(value)
38
+ end
39
+ elsif obj.is_a?(Array)
40
+ obj.map { |value| _deep_symbolize_keys(value) }
41
+ else
42
+ obj
43
+ end
44
+ end
45
+
46
+ def self._create_permission(function)
47
+ policy = function[:policy]
48
+ policy[:Statement].map do |statement|
49
+ # Note that the keys for a statement objection are all CamelCased
50
+ # Whereas most other keys in this repo are snake_cased
51
+ statement.merge(
52
+ {
53
+ _terraform_id: statement[:Sid],
54
+ function_name: function[:function_name],
55
+ function_version: function[:version]
56
+ }
57
+ )
58
+ end
59
+ end
60
+
61
+ # Right now, this only fetches policies for the $LATEST version
62
+ # If we want to support fetching the permissions for all of the aliases as well,
63
+ # We'll need to add another call per function, bring total calls to 2N+1...
64
+ # Same deal if we need to support older versions...
65
+ # (excluding any extra calls for pagination). Less than ideal...
66
+ def self._fetch_remote_resources
67
+ _fetch_functions
68
+ .map { |function| _fetch_policy(function) }
69
+ .compact
70
+ .map { |function| _create_permission(function) }
71
+ .flatten
72
+ .compact
73
+ end
74
+ end
@@ -0,0 +1,51 @@
1
+ ########################################################################
2
+ # AwsMainRouteTableAssociation is the +aws_main_route_table_association+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/main_route_table_assoc.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsMainRouteTableAssociation < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:vpc_id, :route_table_id]) }
8
+
9
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
10
+ after :initialize, -> { _geo_id -> { "#{vpc_id}::#{route_table_id}" } }
11
+
12
+ def to_terraform_state
13
+ tfstate = super
14
+ tfstate[:primary][:attributes] = {
15
+ 'vpc_id' => vpc_id,
16
+ 'route_table_id' => route_table_id
17
+ }
18
+ tfstate
19
+ end
20
+
21
+ def support_tags?
22
+ false
23
+ end
24
+
25
+ def self._fetch_remote_resources
26
+ AwsClients
27
+ .ec2
28
+ .describe_route_tables['route_tables']
29
+ .map(&:to_h)
30
+ .select { |route_table| route_table[:associations] }
31
+ .map { |route_table| _extract_associations(route_table) }
32
+ .flatten
33
+ .select { |association| association[:main] }
34
+ .map { |association| _merge_ids(association) }
35
+ end
36
+
37
+ def self._merge_ids(association)
38
+ association.merge(
39
+ {
40
+ _terraform_id: association[:route_table_association_id],
41
+ _geo_id: "#{association[:vpc_id]}::#{association[:route_table_id]}"
42
+ }
43
+ )
44
+ end
45
+
46
+ def self._extract_associations(route_table)
47
+ route_table[:associations].map do |association|
48
+ association.merge({ vpc_id: route_table[:vpc_id] })
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,29 @@
1
+ ########################################################################
2
+ # AwsNatGateway is the +aws_nat_gateway+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/nat_gateway.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsNatGateway < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:subnet_id, :allocation_id]) }
8
+
9
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
10
+ after :initialize, -> { _geo_id -> { "#{allocation_id}::#{subnet_id}" } }
11
+
12
+ def support_tags?
13
+ false
14
+ end
15
+
16
+ def self._fetch_remote_resources
17
+ AwsClients.ec2.describe_nat_gateways['nat_gateways'].map(&:to_h).map do |gateway|
18
+ # AWS SDK has `nat_gateway_addresses` as an array, but you should only be able to
19
+ # have exactly 1 elastic IP association. This logic should cover the bases...
20
+ allocation = gateway[:nat_gateway_addresses].find { |addr| addr.key?(:allocation_id) }
21
+ gateway.merge(
22
+ {
23
+ _terraform_id: gateway[:nat_gateway_id],
24
+ _geo_id: "#{allocation[:allocation_id]}::#{gateway[:subnet_id]}"
25
+ }
26
+ )
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,38 @@
1
+ ########################################################################
2
+ # AwsNetworkAcl is the +aws_network_acl+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/network_acl.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsNetworkAcl < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:vpc_id]) }
8
+ validate -> { validate_has_tag(:Name) }
9
+ validate -> {
10
+ unless self.all_egress.empty?
11
+ validate_subresource_required_attributes(
12
+ :egress,
13
+ [:from_port, :to_port, :rule_no, :action, :protocol]
14
+ )
15
+ end
16
+
17
+ unless self.all_ingress.empty?
18
+ validate_subresource_required_attributes(
19
+ :ingress,
20
+ [:from_port, :to_port, :rule_no, :action, :protocol]
21
+ )
22
+ end
23
+ }
24
+
25
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
26
+ after :initialize, -> { _geo_id -> { NullObject.maybe(tags)[:Name] } }
27
+
28
+ def self._fetch_remote_resources
29
+ AwsClients.ec2.describe_network_acls['network_acls'].map(&:to_h).map do |network_acl|
30
+ network_acl.merge(
31
+ {
32
+ _terraform_id: network_acl[:network_acl_id],
33
+ _geo_id: network_acl[:tags]&.find { |tag| tag[:key] == "Name" }&.dig(:value)
34
+ }
35
+ )
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,50 @@
1
+ ########################################################################
2
+ # AwsNetworkAclRule is the +aws_network_acl_rule+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/network_acl_rule.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsNetworkAclRule < GeoEngineer::Resource
7
+ validate -> {
8
+ validate_required_attributes(
9
+ [:network_acl_id, :rule_number, :protocol, :rule_action, :cidr_block]
10
+ )
11
+ }
12
+
13
+ after :initialize, -> {
14
+ _terraform_id -> {
15
+ terraform_id_components = [
16
+ "#{network_acl_id}-",
17
+ "#{rule_number}-",
18
+ "#{egress}-",
19
+ "#{protocol == 'all' ? '-1' : protocol}-"
20
+ ]
21
+ "nacl-#{Crc32.hashcode(terraform_id_components.join)}"
22
+ }
23
+ }
24
+
25
+ def support_tags?
26
+ false
27
+ end
28
+
29
+ def self._fetch_remote_resources
30
+ AwsClients
31
+ .ec2
32
+ .describe_network_acls['network_acls']
33
+ .map(&:to_h)
34
+ .select { |network_acl| !network_acl[:entries].empty? }
35
+ .map { |network_acl| _generate_rules(network_acl) }
36
+ .flatten
37
+ end
38
+
39
+ def self._generate_rules(network_acl)
40
+ network_acl[:entries].map do |rule|
41
+ terraform_id_components = [
42
+ "#{network_acl[:network_acl_id]}-",
43
+ "#{rule[:rule_number]}-",
44
+ "#{rule[:egress]}-",
45
+ "#{rule[:protocol] == 'all' ? '-1' : rule[:protocol]}-"
46
+ ]
47
+ rule.merge({ _terraform_id: "nacl-#{Crc32.hashcode(terraform_id_components.join)}" })
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,47 @@
1
+ ########################################################################
2
+ # AwsRoute is the +aws_route+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/route.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsRoute < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:route_table_id, :destination_cidr_block]) }
8
+
9
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
10
+ after :initialize, -> { _geo_id -> { "#{route_table_id}::#{destination_cidr_block}" } }
11
+
12
+ def to_terraform_state
13
+ tfstate = super
14
+ tfstate[:primary][:attributes] = {
15
+ 'route_table_id' => route_table_id,
16
+ 'destination_cidr_block' => destination_cidr_block
17
+ }
18
+ tfstate
19
+ end
20
+
21
+ def support_tags?
22
+ false
23
+ end
24
+
25
+ def self._fetch_remote_resources
26
+ AwsClients
27
+ .ec2
28
+ .describe_route_tables['route_tables']
29
+ .map(&:to_h)
30
+ .map { |route_table| _extract_routes(route_table) }
31
+ .flatten
32
+ .compact
33
+ end
34
+
35
+ def self._extract_routes(route_table)
36
+ route_table[:routes]&.map do |route|
37
+ id = "r-#{route_table[:route_table_id]}#{Crc32.hashcode(route[:destination_cidr_block])}"
38
+ route.merge(
39
+ {
40
+ route_table_id: route_table[:route_table_id],
41
+ _terraform_id: id,
42
+ _geo_id: "#{route_table[:route_table_id]}::#{route[:destination_cidr_block]}"
43
+ }
44
+ )
45
+ end
46
+ end
47
+ end
@@ -15,6 +15,10 @@ class GeoEngineer::Resources::AwsRoute53Record < GeoEngineer::Resource
15
15
 
16
16
  after :initialize, -> { _terraform_id -> { "#{zone_id}_#{name}_#{type}" } }
17
17
 
18
+ def support_tags?
19
+ false
20
+ end
21
+
18
22
  def self._fetch_remote_resources
19
23
  _fetch_zones.map { |zone| _fetch_records_for_zone(zone) }.flatten.compact
20
24
  end
@@ -0,0 +1,26 @@
1
+ ########################################################################
2
+ # AwsRouteTable is the +aws_route_table+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/route_table.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsRouteTable < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:vpc_id]) }
8
+ validate -> { validate_has_tag(:Name) }
9
+ validate -> {
10
+ validate_subresource_required_attributes(:route, [:cider_block]) unless self.all_route.empty?
11
+ }
12
+
13
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
14
+ after :initialize, -> { _geo_id -> { NullObject.maybe(tags)[:Name] } }
15
+
16
+ def self._fetch_remote_resources
17
+ AwsClients.ec2.describe_route_tables['route_tables'].map(&:to_h).map do |route_table|
18
+ route_table.merge(
19
+ {
20
+ _terraform_id: route_table[:route_table_id],
21
+ _geo_id: route_table[:tags]&.find { |tag| tag[:key] == "Name" }&.dig(:value)
22
+ }
23
+ )
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,45 @@
1
+ ########################################################################
2
+ # AwsRouteTableAssociation is the +aws_route_table_association+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/route_table_association.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsRouteTableAssociation < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:subnet_id, :route_table_id]) }
8
+
9
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
10
+ after :initialize, -> { _geo_id -> { "#{subnet_id}::#{route_table_id}" } }
11
+
12
+ def to_terraform_state
13
+ tfstate = super
14
+ tfstate[:primary][:attributes] = {
15
+ 'subnet_id' => subnet_id,
16
+ 'route_table_id' => route_table_id
17
+ }
18
+ tfstate
19
+ end
20
+
21
+ def support_tags?
22
+ false
23
+ end
24
+
25
+ def self._fetch_remote_resources
26
+ AwsClients
27
+ .ec2
28
+ .describe_route_tables['route_tables']
29
+ .map(&:to_h)
30
+ .map { |route_table| route_table[:associations] }
31
+ .flatten
32
+ .compact
33
+ .reject { |association| association[:main] }
34
+ .map { |association| _merge_ids(association) }
35
+ end
36
+
37
+ def self._merge_ids(association)
38
+ association.merge(
39
+ {
40
+ _terraform_id: association[:route_table_association_id],
41
+ _geo_id: "#{association[:subnet_id]}::#{association[:route_table_id]}"
42
+ }
43
+ )
44
+ end
45
+ end
@@ -31,7 +31,7 @@ class GeoEngineer::Resources::AwsSecurityGroup < GeoEngineer::Resource
31
31
  (self.all_ingress + self.all_egress).each do |in_eg|
32
32
  next unless in_eg.cidr_blocks
33
33
  in_eg.cidr_blocks.each do |cidr|
34
- _, error = validate_cidr_block(cidr)
34
+ error = validate_cidr_block(cidr)
35
35
  errors << error unless error.nil?
36
36
  end
37
37
  end
@@ -44,10 +44,13 @@ class GeoEngineer::Resources::AwsSecurityGroup < GeoEngineer::Resource
44
44
 
45
45
  def self._fetch_remote_resources
46
46
  AwsClients.ec2.describe_security_groups['security_groups'].map(&:to_h).map do |sg|
47
- sg[:name] = sg[:group_name]
48
- sg[:_terraform_id] = sg[:group_id]
49
- sg[:_geo_id] = sg[:tags] ? sg[:tags].select { |x| x[:key] == "Name" }.first[:value] : nil
50
- sg
47
+ sg.merge(
48
+ {
49
+ name: sg[:group_name],
50
+ _terraform_id: sg[:group_id],
51
+ _geo_id: sg[:tags]&.find { |tag| tag[:key] == "Name" }&.dig(:value)
52
+ }
53
+ )
51
54
  end
52
55
  end
53
56
  end
@@ -0,0 +1,24 @@
1
+ ########################################################################
2
+ # AwsSubnet is the +aws_subnet+ terrform resource,
3
+ #
4
+ # {https://www.terraform.io/docs/providers/aws/r/subnet.html Terraform Docs}
5
+ ########################################################################
6
+ class GeoEngineer::Resources::AwsSubnet < GeoEngineer::Resource
7
+ validate -> { validate_required_attributes([:cidr_block, :vpc_id]) }
8
+ validate -> { validate_has_tag(:Name) }
9
+ validate -> { validate_cidr_block(self.cidr_block) if self.cidr_block }
10
+
11
+ after :initialize, -> { _terraform_id -> { NullObject.maybe(remote_resource)._terraform_id } }
12
+ after :initialize, -> { _geo_id -> { NullObject.maybe(tags)[:Name] } }
13
+
14
+ def self._fetch_remote_resources
15
+ AwsClients.ec2.describe_subnets['subnets'].map(&:to_h).map do |subnet|
16
+ subnet.merge(
17
+ {
18
+ _terraform_id: subnet[:subnet_id],
19
+ _geo_id: subnet[:tags]&.find { |tag| tag[:key] == "Name" }&.dig(:value)
20
+ }
21
+ )
22
+ end
23
+ end
24
+ end