chef-provisioning-aws 1.3.1 → 1.4.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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +70 -69
  3. data/Rakefile +22 -2
  4. data/lib/chef/provider/aws_auto_scaling_group.rb +3 -2
  5. data/lib/chef/provider/aws_cache_cluster.rb +3 -2
  6. data/lib/chef/provider/aws_cache_replication_group.rb +5 -4
  7. data/lib/chef/provider/aws_cache_subnet_group.rb +5 -4
  8. data/lib/chef/provider/aws_cloudsearch_domain.rb +163 -0
  9. data/lib/chef/provider/aws_dhcp_options.rb +9 -6
  10. data/lib/chef/provider/aws_ebs_volume.rb +7 -3
  11. data/lib/chef/provider/aws_eip_address.rb +8 -7
  12. data/lib/chef/provider/aws_image.rb +8 -3
  13. data/lib/chef/provider/aws_instance.rb +14 -2
  14. data/lib/chef/provider/aws_key_pair.rb +2 -1
  15. data/lib/chef/provider/aws_launch_configuration.rb +4 -2
  16. data/lib/chef/provider/aws_load_balancer.rb +18 -0
  17. data/lib/chef/provider/aws_network_acl.rb +6 -2
  18. data/lib/chef/provider/aws_network_interface.rb +11 -24
  19. data/lib/chef/provider/aws_rds_instance.rb +66 -0
  20. data/lib/chef/provider/aws_rds_subnet_group.rb +89 -0
  21. data/lib/chef/provider/aws_route_table.rb +42 -23
  22. data/lib/chef/provider/aws_s3_bucket.rb +32 -8
  23. data/lib/chef/provider/aws_security_group.rb +11 -4
  24. data/lib/chef/provider/aws_server_certificate.rb +23 -0
  25. data/lib/chef/provider/aws_sns_topic.rb +4 -3
  26. data/lib/chef/provider/aws_sqs_queue.rb +3 -2
  27. data/lib/chef/provider/aws_subnet.rb +10 -7
  28. data/lib/chef/provider/aws_vpc.rb +54 -21
  29. data/lib/chef/provider/aws_vpc_peering_connection.rb +88 -0
  30. data/lib/chef/provisioning/aws_driver.rb +8 -0
  31. data/lib/chef/provisioning/aws_driver/aws_provider.rb +45 -76
  32. data/lib/chef/provisioning/aws_driver/aws_rds_resource.rb +11 -0
  33. data/lib/chef/provisioning/aws_driver/aws_resource.rb +14 -2
  34. data/lib/chef/provisioning/aws_driver/aws_resource_with_entry.rb +2 -8
  35. data/lib/chef/provisioning/aws_driver/aws_taggable.rb +18 -0
  36. data/lib/chef/provisioning/aws_driver/aws_tagger.rb +61 -0
  37. data/lib/chef/provisioning/aws_driver/credentials2.rb +51 -0
  38. data/lib/chef/provisioning/aws_driver/driver.rb +214 -162
  39. data/lib/chef/provisioning/aws_driver/tagging_strategy/ec2.rb +64 -0
  40. data/lib/chef/provisioning/aws_driver/tagging_strategy/elb.rb +39 -0
  41. data/lib/chef/provisioning/aws_driver/tagging_strategy/rds.rb +92 -0
  42. data/lib/chef/provisioning/aws_driver/tagging_strategy/s3.rb +41 -0
  43. data/lib/chef/provisioning/aws_driver/version.rb +1 -1
  44. data/lib/chef/resource/aws_cache_cluster.rb +1 -2
  45. data/lib/chef/resource/aws_cloudsearch_domain.rb +46 -0
  46. data/lib/chef/resource/aws_dhcp_options.rb +2 -0
  47. data/lib/chef/resource/aws_ebs_volume.rb +3 -1
  48. data/lib/chef/resource/aws_eip_address.rb +0 -3
  49. data/lib/chef/resource/aws_image.rb +3 -0
  50. data/lib/chef/resource/aws_instance.rb +7 -2
  51. data/lib/chef/resource/aws_internet_gateway.rb +2 -0
  52. data/lib/chef/resource/aws_load_balancer.rb +3 -0
  53. data/lib/chef/resource/aws_network_acl.rb +2 -0
  54. data/lib/chef/resource/aws_network_interface.rb +3 -1
  55. data/lib/chef/resource/aws_rds_instance.rb +42 -0
  56. data/lib/chef/resource/aws_rds_subnet_group.rb +29 -0
  57. data/lib/chef/resource/aws_route_table.rb +7 -5
  58. data/lib/chef/resource/aws_s3_bucket.rb +3 -0
  59. data/lib/chef/resource/aws_security_group.rb +2 -7
  60. data/lib/chef/resource/aws_server_certificate.rb +21 -0
  61. data/lib/chef/resource/aws_subnet.rb +2 -0
  62. data/lib/chef/resource/aws_vpc.rb +4 -1
  63. data/lib/chef/resource/aws_vpc_peering_connection.rb +73 -0
  64. data/spec/acceptance/aws_ebs_volume/nodes/ettores-mbp.lan.json +3 -0
  65. data/spec/aws_support.rb +25 -8
  66. data/spec/aws_support/aws_resource_run_wrapper.rb +5 -1
  67. data/spec/aws_support/deep_matcher/match_values_failure_messages.rb +19 -0
  68. data/spec/aws_support/matchers/create_an_aws_object.rb +1 -1
  69. data/spec/aws_support/matchers/destroy_an_aws_object.rb +1 -1
  70. data/spec/aws_support/matchers/have_aws_object_tags.rb +9 -15
  71. data/spec/aws_support/matchers/match_an_aws_object.rb +1 -1
  72. data/spec/aws_support/matchers/update_an_aws_object.rb +1 -1
  73. data/spec/integration/aws_cloudsearch_domain_spec.rb +31 -0
  74. data/spec/integration/aws_dhcp_options_spec.rb +73 -0
  75. data/spec/integration/aws_ebs_volume_spec.rb +97 -0
  76. data/spec/integration/aws_network_acl_spec.rb +51 -0
  77. data/spec/integration/aws_network_interface_spec.rb +89 -0
  78. data/spec/integration/aws_rds_instance_spec.rb +150 -0
  79. data/spec/integration/aws_rds_subnet_group_spec.rb +105 -0
  80. data/spec/integration/aws_route_table_spec.rb +94 -7
  81. data/spec/integration/aws_s3_bucket_spec.rb +88 -0
  82. data/spec/integration/aws_security_group_spec.rb +47 -0
  83. data/spec/integration/aws_server_certificate_spec.rb +24 -0
  84. data/spec/integration/aws_subnet_spec.rb +51 -2
  85. data/spec/integration/aws_vpc_peering_connection_spec.rb +99 -0
  86. data/spec/integration/aws_vpc_spec.rb +73 -0
  87. data/spec/integration/load_balancer_spec.rb +101 -0
  88. data/spec/integration/machine_image_spec.rb +61 -6
  89. data/spec/integration/machine_spec.rb +26 -0
  90. data/spec/spec_helper.rb +3 -0
  91. data/spec/unit/{aws_driver → chef/provisioning/aws_driver}/credentials_spec.rb +0 -0
  92. data/spec/unit/chef/provisioning/aws_driver/driver_spec.rb +88 -0
  93. metadata +63 -20
  94. data/spec/integration/aws_tagged_items_spec.rb +0 -166
@@ -2,6 +2,9 @@ require 'chef/provisioning/aws_driver/aws_provider'
2
2
  require 'retryable'
3
3
 
4
4
  class Chef::Provider::AwsRouteTable < Chef::Provisioning::AWSDriver::AWSProvider
5
+ include Chef::Provisioning::AWSDriver::TaggingStrategy::EC2ConvergeTags
6
+
7
+ provides :aws_route_table
5
8
 
6
9
  def action_create
7
10
  route_table = super
@@ -17,14 +20,23 @@ class Chef::Provider::AwsRouteTable < Chef::Provisioning::AWSDriver::AWSProvider
17
20
 
18
21
  def create_aws_object
19
22
  options = {}
20
- options[:vpc] = new_resource.vpc
23
+ options[:vpc_id] = new_resource.vpc
21
24
  options = AWSResource.lookup_options(options, resource: new_resource)
22
- self.vpc = Chef::Resource::AwsVpc.get_aws_object(options[:vpc], resource: new_resource)
23
25
 
24
- converge_by "create new route table #{new_resource.name} in VPC #{new_resource.vpc} (#{vpc.id}) and region #{region}" do
25
- route_table = new_resource.driver.ec2.route_tables.create(options)
26
- retry_with_backoff(AWS::EC2::Errors::InvalidRouteTableID::NotFound) do
27
- route_table.tags['Name'] = new_resource.name
26
+ ec2_resource = new_resource.driver.ec2_resource
27
+ self.vpc = ec2_resource.vpc(options[:vpc_id])
28
+
29
+ converge_by "create route table #{new_resource.name} in VPC #{new_resource.vpc} (#{vpc.id}) and region #{region}" do
30
+ route_table = vpc.create_route_table
31
+ retry_with_backoff(::Aws::EC2::Errors::ServiceError) do
32
+ route_table.create_tags({
33
+ :tags => [
34
+ {
35
+ :key => "Name",
36
+ :value => new_resource.name
37
+ }
38
+ ]
39
+ })
28
40
  end
29
41
  route_table
30
42
  end
@@ -34,9 +46,9 @@ class Chef::Provider::AwsRouteTable < Chef::Provisioning::AWSDriver::AWSProvider
34
46
  self.vpc = route_table.vpc
35
47
 
36
48
  if new_resource.vpc
37
- desired_vpc = Chef::Resource::AwsVpc.get_aws_object(new_resource.vpc, resource: new_resource)
38
- if vpc != desired_vpc
39
- raise "VPC of route table #{new_resource.to_s} is #{route_table.vpc.id}, but desired vpc is #{new_resource.vpc}! The AWS SDK does not support updating the main route table except by creating a new route table."
49
+ desired_vpc_id = Chef::Resource::AwsVpc.get_aws_object_id(new_resource.vpc, resource: new_resource)
50
+ if vpc.id != desired_vpc_id
51
+ raise "VPC of route table #{new_resource.to_s} is #{vpc.id}, but desired VPC is #{desired_vpc_id}! The AWS SDK does not support updating the main route table except by creating a new route table."
40
52
  end
41
53
  end
42
54
  end
@@ -45,7 +57,7 @@ class Chef::Provider::AwsRouteTable < Chef::Provisioning::AWSDriver::AWSProvider
45
57
  converge_by "delete #{new_resource.to_s} in #{region}" do
46
58
  begin
47
59
  route_table.delete
48
- rescue AWS::EC2::Errors::DependencyViolation
60
+ rescue ::Aws::EC2::Errors::DependencyViolation
49
61
  raise "#{new_resource.to_s} could not be deleted because it is the main route table for #{route_table.vpc.id} or it is being used by a subnet"
50
62
  end
51
63
  end
@@ -60,8 +72,9 @@ class Chef::Provider::AwsRouteTable < Chef::Provisioning::AWSDriver::AWSProvider
60
72
  current_routes = {}
61
73
  route_table.routes.each do |route|
62
74
  # Ignore the automatic local route
63
- next if route.target.id == 'local'
64
- next if ignore_route_targets.find { |target| route.target.id.match(/#{target}/) }
75
+ route_target = route.gateway_id || route.instance_id || route.network_interface_id || route.vpc_peering_connection_id
76
+ next if route_target == 'local'
77
+ next if ignore_route_targets.find { |target| route_target.match(/#{target}/) }
65
78
  current_routes[route.destination_cidr_block] = route
66
79
  end
67
80
 
@@ -72,14 +85,15 @@ class Chef::Provider::AwsRouteTable < Chef::Provisioning::AWSDriver::AWSProvider
72
85
  # If we already have a route to that CIDR block, replace it.
73
86
  if current_routes[destination_cidr_block]
74
87
  current_route = current_routes.delete(destination_cidr_block)
75
- if current_route.target != target
76
- action_handler.perform_action "reroute #{destination_cidr_block} to #{route_target} (#{target.id}) instead of #{current_route.target.id}" do
88
+ current_target = current_route.gateway_id || current_route.instance_id || current_route.network_interface_id || current_route.vpc_peering_connection_id
89
+ if current_target != target
90
+ action_handler.perform_action "reroute #{destination_cidr_block} to #{route_target} (#{target}) instead of #{current_route.target}" do
77
91
  current_route.replace(options)
78
92
  end
79
93
  end
80
94
  else
81
- action_handler.perform_action "route #{destination_cidr_block} to #{route_target} (#{target.id})" do
82
- route_table.create_route(destination_cidr_block, options)
95
+ action_handler.perform_action "route #{destination_cidr_block} to #{route_target} (#{target})" do
96
+ route_table.create_route({ :destination_cidr_block => destination_cidr_block }.merge(options))
83
97
  end
84
98
  end
85
99
  end
@@ -93,7 +107,7 @@ class Chef::Provider::AwsRouteTable < Chef::Provisioning::AWSDriver::AWSProvider
93
107
  end
94
108
 
95
109
  def update_virtual_private_gateways(route_table, gateway_ids)
96
- current_propagating_vgw_set = route_table.client.describe_route_tables(route_table_ids: [route_table.id]).route_table_set.first.propagating_vgw_set
110
+ current_propagating_vgw_set = route_table.propagating_vgws
97
111
 
98
112
  # Add propagated routes
99
113
  if gateway_ids
@@ -119,7 +133,7 @@ class Chef::Provider::AwsRouteTable < Chef::Provisioning::AWSDriver::AWSProvider
119
133
  def get_route_target(vpc, route_target)
120
134
  case route_target
121
135
  when :internet_gateway
122
- route_target = { internet_gateway: vpc.internet_gateway }
136
+ route_target = { internet_gateway: vpc.internet_gateways.first.id }
123
137
  if !route_target[:internet_gateway]
124
138
  raise "VPC #{new_resource.vpc} (#{vpc.id}) does not have an internet gateway to route to! Use `internet_gateway true` on the VPC itself to create one."
125
139
  end
@@ -127,11 +141,13 @@ class Chef::Provider::AwsRouteTable < Chef::Provisioning::AWSDriver::AWSProvider
127
141
  route_target = { internet_gateway: route_target }
128
142
  when /^eni-[A-Fa-f0-9]{8}$/, Chef::Resource::AwsNetworkInterface, AWS::EC2::NetworkInterface
129
143
  route_target = { network_interface: route_target }
144
+ when /^pcx-[A-Fa-f0-9]{8}$/, Chef::Resource::AwsVpcPeeringConnection, ::Aws::EC2::AwsVpcPeeringConnection
145
+ route_target = { vpc_peering_connection: route_target }
130
146
  when String, Chef::Resource::AwsInstance
131
147
  route_target = { instance: route_target }
132
148
  when Chef::Resource::Machine
133
149
  route_target = { instance: route_target.name }
134
- when AWS::EC2::Instance
150
+ when AWS::EC2::Instance, ::Aws::EC2::Instance
135
151
  route_target = { instance: route_target.id }
136
152
  when Hash
137
153
  if route_target.size != 1
@@ -141,16 +157,19 @@ class Chef::Provider::AwsRouteTable < Chef::Provisioning::AWSDriver::AWSProvider
141
157
  else
142
158
  raise "Unrecognized route destination #{route_target.inspect}"
143
159
  end
160
+ updated_route_target = {}
144
161
  route_target.each do |name, value|
145
162
  case name
146
163
  when :instance
147
- route_target[name] = Chef::Resource::AwsInstance.get_aws_object(value, resource: new_resource)
164
+ updated_route_target[:instance_id] = Chef::Resource::AwsInstance.get_aws_object_id(value, resource: new_resource)
148
165
  when :network_interface
149
- route_target[name] = Chef::Resource::AwsNetworkInterface.get_aws_object(value, resource: new_resource)
166
+ updated_route_target[:network_interface_id] = Chef::Resource::AwsNetworkInterface.get_aws_object_id(value, resource: new_resource)
150
167
  when :internet_gateway
151
- route_target[name] = Chef::Resource::AwsInternetGateway.get_aws_object(value, resource: new_resource)
168
+ updated_route_target[:gateway_id] = Chef::Resource::AwsInternetGateway.get_aws_object_id(value, resource: new_resource)
169
+ when :vpc_peering_connection
170
+ updated_route_target[:vpc_peering_connection_id] = Chef::Resource::AwsVpcPeeringConnection.get_aws_object_id(value, resource: new_resource)
152
171
  end
153
172
  end
154
- route_target
173
+ updated_route_target
155
174
  end
156
175
  end
@@ -1,25 +1,45 @@
1
1
  require 'chef/provisioning/aws_driver/aws_provider'
2
+ require 'chef/provisioning/aws_driver/tagging_strategy/s3'
2
3
  require 'date'
3
4
 
4
5
  class Chef::Provider::AwsS3Bucket < Chef::Provisioning::AWSDriver::AWSProvider
6
+
7
+ def aws_tagger
8
+ @aws_tagger ||= begin
9
+ s3_strategy = Chef::Provisioning::AWSDriver::TaggingStrategy::S3.new(
10
+ # I'm using the V2 client here because it has much better support for tags
11
+ new_resource.driver.s3_client,
12
+ new_resource.name,
13
+ new_resource.aws_tags
14
+ )
15
+ Chef::Provisioning::AWSDriver::AWSTagger.new(s3_strategy, action_handler)
16
+ end
17
+ end
18
+
19
+ def converge_tags
20
+ aws_tagger.converge_tags
21
+ end
22
+
23
+ provides :aws_s3_bucket
24
+
5
25
  def action_create
6
26
  bucket = super
7
27
 
8
28
  if new_resource.enable_website_hosting
9
29
  if !bucket.website?
10
- converge_by "Enabling website configuration for bucket #{new_resource.name}" do
30
+ converge_by "enable website configuration for bucket #{new_resource.name}" do
11
31
  bucket.website_configuration = AWS::S3::WebsiteConfiguration.new(
12
32
  new_resource.website_options)
13
33
  end
14
34
  elsif modifies_website_configuration?(bucket)
15
- converge_by "Reconfiguring website configuration for bucket #{new_resource.name} to #{new_resource.website_options}" do
35
+ converge_by "reconfigure website configuration for bucket #{new_resource.name} to #{new_resource.website_options}" do
16
36
  bucket.website_configuration = AWS::S3::WebsiteConfiguration.new(
17
37
  new_resource.website_options)
18
38
  end
19
39
  end
20
40
  else
21
41
  if bucket.website?
22
- converge_by "Disabling website configuration for bucket #{new_resource.name}" do
42
+ converge_by "disable website configuration for bucket #{new_resource.name}" do
23
43
  bucket.website_configuration = nil
24
44
  end
25
45
  end
@@ -29,10 +49,10 @@ class Chef::Provider::AwsS3Bucket < Chef::Provisioning::AWSDriver::AWSProvider
29
49
  protected
30
50
 
31
51
  def create_aws_object
32
- converge_by "create new S3 bucket #{new_resource.name}" do
33
- bucket = new_resource.driver.s3.buckets.create(new_resource.name)
34
- bucket.tags['Name'] = new_resource.name
35
- bucket
52
+ converge_by "create S3 bucket #{new_resource.name}" do
53
+ new_resource.driver.s3.buckets.create(new_resource.name)
54
+ # S3 buckets already have a top level name property so they don't need
55
+ # a 'Name' tag
36
56
  end
37
57
  end
38
58
 
@@ -41,7 +61,11 @@ class Chef::Provider::AwsS3Bucket < Chef::Provisioning::AWSDriver::AWSProvider
41
61
 
42
62
  def destroy_aws_object(bucket)
43
63
  converge_by "delete S3 bucket #{new_resource.name}" do
44
- bucket.delete
64
+ if new_resource.recursive_delete
65
+ bucket.delete!
66
+ else
67
+ bucket.delete
68
+ end
45
69
  end
46
70
  end
47
71
 
@@ -4,6 +4,9 @@ require 'ipaddr'
4
4
  require 'set'
5
5
 
6
6
  class Chef::Provider::AwsSecurityGroup < Chef::Provisioning::AWSDriver::AWSProvider
7
+ include Chef::Provisioning::AWSDriver::TaggingStrategy::EC2ConvergeTags
8
+
9
+ provides :aws_security_group
7
10
 
8
11
  def action_create
9
12
  sg = super
@@ -14,31 +17,35 @@ class Chef::Provider::AwsSecurityGroup < Chef::Provisioning::AWSDriver::AWSProvi
14
17
  protected
15
18
 
16
19
  def create_aws_object
17
- converge_by "Creating new SG #{new_resource.name} in #{region}" do
20
+ converge_by "create security group #{new_resource.name} in #{region}" do
18
21
  options = { description: new_resource.description }
19
22
  options[:vpc] = new_resource.vpc if new_resource.vpc
20
23
  options = AWSResource.lookup_options(options, resource: new_resource)
21
24
  Chef::Log.debug("VPC: #{options[:vpc]}")
22
25
 
23
26
  sg = new_resource.driver.ec2.security_groups.create(new_resource.name, options)
27
+ retry_with_backoff(AWS::EC2::Errors::InvalidSecurityGroupsID::NotFound) do
28
+ sg.tags['Name'] = new_resource.name
29
+ end
30
+ sg
24
31
  end
25
32
  end
26
33
 
27
34
  def update_aws_object(sg)
28
35
  if !new_resource.description.nil? && new_resource.description != sg.description
29
- raise "Security Group descriptions cannot be changed after being created! Desired description for #{new_resource.name} (#{sg.id}) was \"#{new_resource.description}\" and actual description is \"#{sg.description}\""
36
+ raise "Security group descriptions cannot be changed after being created! Desired description for #{new_resource.name} (#{sg.id}) was \"#{new_resource.description}\" and actual description is \"#{sg.description}\""
30
37
  end
31
38
  if !new_resource.vpc.nil?
32
39
  desired_vpc = Chef::Resource::AwsVpc.get_aws_object_id(new_resource.vpc, resource: new_resource)
33
40
  if desired_vpc != sg.vpc_id
34
- raise "Security Group VPC cannot be changed after being created! Desired VPC for #{new_resource.name} (#{sg.id}) was #{new_resource.vpc} (#{desired_vpc}) and actual VPC is #{sg.vpc_id}"
41
+ raise "Security group VPC cannot be changed after being created! Desired VPC for #{new_resource.name} (#{sg.id}) was #{new_resource.vpc} (#{desired_vpc}) and actual VPC is #{sg.vpc_id}"
35
42
  end
36
43
  end
37
44
  apply_rules(sg)
38
45
  end
39
46
 
40
47
  def destroy_aws_object(sg)
41
- converge_by "delete #{new_resource.to_s} in #{region}" do
48
+ converge_by "delete security group #{new_resource.to_s} in #{region}" do
42
49
  sg.delete
43
50
  end
44
51
  end
@@ -0,0 +1,23 @@
1
+ require 'chef/provisioning/aws_driver/aws_provider'
2
+
3
+ class Chef::Provider::AwsServerCertificate < Chef::Provisioning::AWSDriver::AWSProvider
4
+ provides :aws_server_certificate
5
+
6
+ def update_aws_object(certificate)
7
+ Chef::Log.warn("aws_server_certificate does not support modifying an existing certificate")
8
+ end
9
+
10
+ def create_aws_object
11
+ converge_by "create server certificate #{new_resource.name}" do
12
+ new_resource.driver.iam.server_certificates.upload(:name => new_resource.name,
13
+ :certificate_body => new_resource.certificate_body,
14
+ :private_key => new_resource.private_key)
15
+ end
16
+ end
17
+
18
+ def destroy_aws_object(certificate)
19
+ converge_by "delete server certificate #{new_resource.name}" do
20
+ certificate.delete
21
+ end
22
+ end
23
+ end
@@ -2,11 +2,12 @@ require 'chef/provisioning/aws_driver/aws_provider'
2
2
  require 'date'
3
3
 
4
4
  class Chef::Provider::AwsSnsTopic < Chef::Provisioning::AWSDriver::AWSProvider
5
-
5
+ provides :aws_sns_topic
6
+
6
7
  protected
7
8
 
8
9
  def create_aws_object
9
- converge_by "Creating new SNS topic #{new_resource.name} in #{region}" do
10
+ converge_by "create SNS topic #{new_resource.name} in #{region}" do
10
11
  new_resource.driver.sns.topics.create(new_resource.name)
11
12
  end
12
13
  end
@@ -15,7 +16,7 @@ class Chef::Provider::AwsSnsTopic < Chef::Provisioning::AWSDriver::AWSProvider
15
16
  end
16
17
 
17
18
  def destroy_aws_object(topic)
18
- converge_by "Deleting SNS topic #{topic.name} in #{region}" do
19
+ converge_by "delete SNS topic #{topic.name} in #{region}" do
19
20
  topic.delete
20
21
  end
21
22
  end
@@ -1,9 +1,10 @@
1
1
  require 'chef/provisioning/aws_driver/aws_provider'
2
2
 
3
3
  class Chef::Provider::AwsSqsQueue < Chef::Provisioning::AWSDriver::AWSProvider
4
-
4
+ provides :aws_sqs_queue
5
+
5
6
  def create_aws_object
6
- converge_by "create new SQS queue #{new_resource.name} in #{region}" do
7
+ converge_by "create SQS queue #{new_resource.name} in #{region}" do
7
8
  retry_with_backoff(AWS::SQS::Errors::QueueDeletedRecently) do
8
9
  new_resource.driver.sqs.queues.create(new_resource.name, new_resource.options || {})
9
10
  end
@@ -4,6 +4,9 @@ require 'date'
4
4
  require 'chef/resource/aws_vpc'
5
5
 
6
6
  class Chef::Provider::AwsSubnet < Chef::Provisioning::AWSDriver::AWSProvider
7
+ include Chef::Provisioning::AWSDriver::TaggingStrategy::EC2ConvergeTags
8
+
9
+ provides :aws_subnet
7
10
 
8
11
  def action_create
9
12
  subnet = super
@@ -30,7 +33,7 @@ class Chef::Provider::AwsSubnet < Chef::Provisioning::AWSDriver::AWSProvider
30
33
  options[:availability_zone] = new_resource.availability_zone if new_resource.availability_zone
31
34
  options = Chef::Provisioning::AWSDriver::AWSResource.lookup_options(options, resource: new_resource)
32
35
 
33
- converge_by "create new subnet #{new_resource.name} with CIDR #{cidr_block} in VPC #{new_resource.vpc} (#{options[:vpc]}) in #{region}" do
36
+ converge_by "create subnet #{new_resource.name} with CIDR #{cidr_block} in VPC #{new_resource.vpc} (#{options[:vpc]}) in #{region}" do
34
37
  subnet = new_resource.driver.ec2.subnets.create(cidr_block, options)
35
38
  retry_with_backoff(AWS::EC2::Errors::InvalidSubnetID::NotFound) do
36
39
  subnet.tags['Name'] = new_resource.name
@@ -47,7 +50,7 @@ class Chef::Provider::AwsSubnet < Chef::Provisioning::AWSDriver::AWSProvider
47
50
  end
48
51
  vpc = Chef::Resource::AwsVpc.get_aws_object(new_resource.vpc, resource: new_resource)
49
52
  if vpc && subnet.vpc != vpc
50
- raise "vpc for subnet #{new_resource.name} is #{new_resource.vpc} (#{vpc.id}), but existing subnet (#{subnet.id})'s vpc is #{subnet.vpc.id}. Modification of subnet vpc is unsupported!"
53
+ raise "VPC for subnet #{new_resource.name} is #{new_resource.vpc} (#{vpc.id}), but existing subnet (#{subnet.id})'s vpc is #{subnet.vpc.id}. Modification of subnet VPC is unsupported!"
51
54
  end
52
55
  if new_resource.availability_zone && subnet.availability_zone_name != new_resource.availability_zone
53
56
  raise "availability_zone for subnet #{new_resource.name} is #{new_resource.availability_zone}, but existing subnet (#{subnet.id})'s availability_zone is #{subnet.availability_zone}. Modification of subnet availability_zone is unsupported!"
@@ -60,7 +63,7 @@ class Chef::Provider::AwsSubnet < Chef::Provisioning::AWSDriver::AWSProvider
60
63
  p = Chef::ChefFS::Parallelizer.new(5)
61
64
  p.parallel_do(subnet.instances.to_a) do |instance|
62
65
  Cheffish.inline_resource(self, action) do
63
- aws_instance instance do
66
+ aws_instance instance.id do
64
67
  action :purge
65
68
  end
66
69
  end
@@ -118,12 +121,12 @@ class Chef::Provider::AwsSubnet < Chef::Provisioning::AWSDriver::AWSProvider
118
121
  # we have work to do here: we need to make the relationship explicit so that
119
122
  # it won't be changed when the main route table of the VPC changes.
120
123
  converge_by "set route table of subnet #{new_resource.name} to #{new_resource.route_table}" do
121
- subnet.route_table = route_table
124
+ subnet.route_table = route_table.id
122
125
  end
123
- elsif current_route_table_association.route_table != route_table
126
+ elsif current_route_table_association.route_table.id != route_table.id
124
127
  # The route table is different now. Change it.
125
128
  converge_by "change route table of subnet #{new_resource.name} to #{new_resource.route_table} (was #{current_route_table_association.route_table.id})" do
126
- subnet.route_table = route_table
129
+ subnet.route_table = route_table.id
127
130
  end
128
131
  end
129
132
  end
@@ -134,7 +137,7 @@ class Chef::Provider::AwsSubnet < Chef::Provisioning::AWSDriver::AWSProvider
134
137
  network_acl_id =
135
138
  AWSResource.lookup_options({ network_acl: new_resource.network_acl }, resource: new_resource)[:network_acl]
136
139
  if subnet.network_acl.id != network_acl_id
137
- converge_by "update network acl of subnet #{new_resource.name} to #{new_resource.network_acl}" do
140
+ converge_by "update network ACL of subnet #{new_resource.name} to #{new_resource.network_acl}" do
138
141
  subnet.network_acl = network_acl_id
139
142
  end
140
143
  end
@@ -4,6 +4,9 @@ require 'chef/provisioning'
4
4
  require 'retryable'
5
5
 
6
6
  class Chef::Provider::AwsVpc < Chef::Provisioning::AWSDriver::AWSProvider
7
+ include Chef::Provisioning::AWSDriver::TaggingStrategy::EC2ConvergeTags
8
+
9
+ provides :aws_vpc
7
10
 
8
11
  class NeverObtainedExistence < RuntimeError; end
9
12
 
@@ -42,10 +45,12 @@ class Chef::Provider::AwsVpc < Chef::Provisioning::AWSDriver::AWSProvider
42
45
  options = { }
43
46
  options[:instance_tenancy] = new_resource.instance_tenancy if new_resource.instance_tenancy
44
47
 
45
- converge_by "create new VPC #{new_resource.name} in #{region}" do
48
+ converge_by "create VPC #{new_resource.name} in #{region}" do
46
49
  vpc = new_resource.driver.ec2.vpcs.create(new_resource.cidr_block, options)
47
50
  wait_for_state(vpc, [:available])
48
- vpc.tags['Name'] = new_resource.name
51
+ retry_with_backoff(AWS::EC2::Errors::InvalidVpcID::NotFound) do
52
+ vpc.tags['Name'] = new_resource.name
53
+ end
49
54
  vpc
50
55
  end
51
56
  end
@@ -78,34 +83,62 @@ class Chef::Provider::AwsVpc < Chef::Provisioning::AWSDriver::AWSProvider
78
83
  end
79
84
  end
80
85
  end
81
- vpc.route_tables.each do |rt|
82
- unless rt.main?
86
+
87
+ vpc.security_groups.each do |sg|
88
+ unless sg.name == 'default'
83
89
  Cheffish.inline_resource(self, action) do
84
- aws_route_table rt do
90
+ aws_security_group sg do
85
91
  action :purge
86
92
  end
87
93
  end
88
94
  end
89
95
  end
90
- vpc.security_groups.each do |sg|
91
- unless sg.name == 'default'
96
+
97
+ #SDK V2
98
+ vpc_new_sdk = new_resource.driver.ec2_resource.vpc(vpc.id)
99
+ vpc_new_sdk.route_tables.each do |rt|
100
+ unless rt.associations.any? { |association| association.main }
92
101
  Cheffish.inline_resource(self, action) do
93
- aws_security_group sg do
102
+ aws_route_table rt do
94
103
  action :purge
95
104
  end
96
105
  end
97
106
  end
98
107
  end
108
+
109
+ vpc_peering_connections = []
110
+ %w(
111
+ requester-vpc-info.vpc-id
112
+ accepter-vpc-info.vpc-id
113
+ ).each do |filter|
114
+ vpc_peering_connections += new_resource.driver.ec2_client.describe_vpc_peering_connections({
115
+ :filters => [
116
+ {
117
+ :name => filter,
118
+ :values => [vpc.id]
119
+ }
120
+ ]
121
+ }).vpc_peering_connections
122
+ end
123
+
124
+ vpc_peering_connections.each do |pc_type|
125
+ pc_resource = new_resource.driver.ec2_resource.vpc_peering_connection(pc_type.vpc_peering_connection_id)
126
+ Cheffish.inline_resource(self, action) do
127
+ aws_vpc_peering_connection pc_resource do
128
+ action :purge
129
+ end
130
+ end
131
+ end
99
132
  end
100
133
 
101
134
  # Detach or destroy the internet gateway
102
135
  ig = vpc.internet_gateway
103
136
  if ig
104
- converge_by "detach Internet Gateway #{ig.id} in #{region} from #{new_resource.to_s}" do
137
+ converge_by "detach Internet gateway #{ig.id} in #{region} from #{new_resource.to_s}" do
105
138
  ig.detach(vpc.id)
106
139
  end
107
140
  if ig.tags['OwnedByVPC'] == vpc.id
108
- converge_by "destroy Internet Gateway #{ig.id} in #{region} (owned by #{new_resource.to_s})" do
141
+ converge_by "destroy Internet gateway #{ig.id} in #{region} (owned by #{new_resource.to_s})" do
109
142
  ig.delete
110
143
  end
111
144
  end
@@ -149,40 +182,40 @@ class Chef::Provider::AwsVpc < Chef::Provisioning::AWSDriver::AWSProvider
149
182
  when String, Chef::Resource::AwsInternetGateway, AWS::EC2::InternetGateway
150
183
  new_ig = Chef::Resource::AwsInternetGateway.get_aws_object(new_resource.internet_gateway, resource: new_resource)
151
184
  if !current_ig
152
- converge_by "attach Internet Gateway #{new_resource.internet_gateway} to VPC #{vpc.id}" do
185
+ converge_by "attach Internet gateway #{new_resource.internet_gateway} to VPC #{vpc.id}" do
153
186
  new_ig.attach(vpc.id)
154
187
  end
155
188
  elsif current_ig != new_ig
156
- converge_by "replace Internet Gateway #{current_ig.id} on VPC #{vpc.id} with new Internet Gateway #{new_ig.id}" do
189
+ converge_by "replace Internet gateway #{current_ig.id} on VPC #{vpc.id} with new Internet gateway #{new_ig.id}" do
157
190
  current_ig.detach(vpc.id)
158
191
  new_ig.attach(vpc.id)
159
192
  end
160
193
  if current_ig.tags['OwnedByVPC'] == vpc.id
161
- converge_by "destroy Internet Gateway #{current_ig.id} in #{region} (owned by VPC #{vpc.id})" do
194
+ converge_by "destroy Internet gateway #{current_ig.id} in #{region} (owned by VPC #{vpc.id})" do
162
195
  current_ig.delete
163
196
  end
164
197
  end
165
198
  end
166
199
  when true
167
200
  if !current_ig
168
- converge_by "attach new Internet Gateway to VPC #{vpc.id}" do
201
+ converge_by "attach Internet gateway to VPC #{vpc.id}" do
169
202
  current_ig = AWS.ec2(config: vpc.config).internet_gateways.create
170
203
  retry_with_backoff(NeverObtainedExistence) do
171
- raise NeverObtainedExistence.new("internet gateway for VPC #{vpc.id} never obtained existence") unless current_ig.exists?
204
+ raise NeverObtainedExistence.new("Internet gateway for VPC #{vpc.id} never obtained existence") unless current_ig.exists?
172
205
  end
173
- action_handler.report_progress "create Internet Gateway #{current_ig.id}"
206
+ action_handler.report_progress "create Internet gateway #{current_ig.id}"
174
207
  current_ig.tags['OwnedByVPC'] = vpc.id
175
- action_handler.report_progress "tag Internet Gateway #{current_ig.id} as OwnedByVpc: #{vpc.id}"
208
+ action_handler.report_progress "tag Internet gateway #{current_ig.id} as OwnedByVpc: #{vpc.id}"
176
209
  vpc.internet_gateway = current_ig
177
210
  end
178
211
  end
179
212
  when false
180
213
  if current_ig
181
- converge_by "detach Internet Gateway #{current_ig.id} from VPC #{vpc.id}" do
214
+ converge_by "detach Internet gateway #{current_ig.id} from VPC #{vpc.id}" do
182
215
  current_ig.detach(vpc.id)
183
216
  end
184
217
  if current_ig.tags['OwnedByVPC'] == vpc.id
185
- converge_by "destroy Internet Gateway #{current_ig.id} in #{region} (owned by VPC #{vpc.id})" do
218
+ converge_by "destroy Internet gateway #{current_ig.id} in #{region} (owned by VPC #{vpc.id})" do
186
219
  current_ig.delete
187
220
  end
188
221
  end
@@ -193,7 +226,7 @@ class Chef::Provider::AwsVpc < Chef::Provisioning::AWSDriver::AWSProvider
193
226
  def update_main_route_table(vpc)
194
227
  desired_route_table = Chef::Resource::AwsRouteTable.get_aws_object(new_resource.main_route_table, resource: new_resource)
195
228
  current_route_table = vpc.route_tables.main_route_table
196
- if current_route_table != desired_route_table
229
+ if current_route_table.id != desired_route_table.id
197
230
  main_association = current_route_table.associations.select { |a| a.main? }.first
198
231
  if !main_association
199
232
  raise "No main route table association found for #{new_resource.to_s} current main route table #{current_route_table.id}: error! Probably a race condition."
@@ -214,7 +247,7 @@ class Chef::Provider::AwsVpc < Chef::Provisioning::AWSDriver::AWSProvider
214
247
  # creating the VPC
215
248
  main_route_table ||= vpc.route_tables.main_route_table
216
249
  main_routes = new_resource.main_routes
217
- aws_route_table main_route_table do
250
+ aws_route_table main_route_table.id do
218
251
  vpc vpc
219
252
  routes main_routes
220
253
  end