chef-provisioning-aws 1.4.1 → 1.5.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.
- checksums.yaml +4 -4
- data/Gemfile +8 -0
- data/README.md +26 -39
- data/Rakefile +13 -5
- data/lib/chef/provider/aws_iam_instance_profile.rb +60 -0
- data/lib/chef/provider/aws_iam_role.rb +98 -0
- data/lib/chef/provider/aws_image.rb +1 -1
- data/lib/chef/provider/aws_internet_gateway.rb +75 -0
- data/lib/chef/provider/aws_route_table.rb +3 -2
- data/lib/chef/provider/aws_s3_bucket.rb +4 -1
- data/lib/chef/provider/aws_security_group.rb +1 -1
- data/lib/chef/provider/aws_vpc.rb +50 -45
- data/lib/chef/provisioning/aws_driver.rb +22 -1
- data/lib/chef/provisioning/aws_driver/aws_provider.rb +13 -5
- data/lib/chef/provisioning/aws_driver/aws_resource.rb +173 -165
- data/lib/chef/provisioning/aws_driver/credentials.rb +12 -0
- data/lib/chef/provisioning/aws_driver/driver.rb +82 -37
- data/lib/chef/provisioning/aws_driver/super_lwrp.rb +56 -43
- data/lib/chef/provisioning/aws_driver/version.rb +1 -1
- data/lib/chef/resource/aws_dhcp_options.rb +1 -1
- data/lib/chef/resource/aws_ebs_volume.rb +1 -1
- data/lib/chef/resource/aws_eip_address.rb +1 -1
- data/lib/chef/resource/aws_iam_instance_profile.rb +33 -0
- data/lib/chef/resource/aws_iam_role.rb +55 -0
- data/lib/chef/resource/aws_image.rb +1 -1
- data/lib/chef/resource/aws_instance.rb +1 -1
- data/lib/chef/resource/aws_internet_gateway.rb +36 -6
- data/lib/chef/resource/aws_load_balancer.rb +1 -1
- data/lib/chef/resource/aws_network_acl.rb +1 -1
- data/lib/chef/resource/aws_network_interface.rb +1 -1
- data/lib/chef/resource/aws_route53_hosted_zone.rb +261 -0
- data/lib/chef/resource/aws_route53_record_set.rb +162 -0
- data/lib/chef/resource/aws_route_table.rb +1 -1
- data/lib/chef/resource/aws_security_group.rb +1 -1
- data/lib/chef/resource/aws_sns_topic.rb +1 -1
- data/lib/chef/resource/aws_subnet.rb +1 -1
- data/lib/chef/resource/aws_vpc.rb +1 -1
- data/lib/chef/resource/aws_vpc_peering_connection.rb +1 -1
- data/spec/aws_support.rb +11 -13
- data/spec/aws_support/matchers/create_an_aws_object.rb +7 -1
- data/spec/aws_support/matchers/have_aws_object_tags.rb +1 -1
- data/spec/aws_support/matchers/match_an_aws_object.rb +7 -1
- data/spec/aws_support/matchers/update_an_aws_object.rb +8 -2
- data/spec/integration/aws_eip_address_spec.rb +74 -0
- data/spec/integration/aws_iam_instance_profile_spec.rb +159 -0
- data/spec/integration/aws_iam_role_spec.rb +177 -0
- data/spec/integration/aws_internet_gateway_spec.rb +161 -0
- data/spec/integration/aws_network_interface_spec.rb +3 -4
- data/spec/integration/aws_route53_hosted_zone_spec.rb +522 -0
- data/spec/integration/aws_route_table_spec.rb +52 -4
- data/spec/integration/aws_s3_bucket_spec.rb +1 -1
- data/spec/integration/load_balancer_spec.rb +303 -8
- data/spec/integration/machine_batch_spec.rb +1 -0
- data/spec/integration/machine_image_spec.rb +32 -17
- data/spec/integration/machine_spec.rb +11 -29
- data/spec/unit/chef/provisioning/aws_driver/driver_spec.rb +0 -1
- data/spec/unit/chef/provisioning/aws_driver/route53_spec.rb +105 -0
- metadata +48 -6
@@ -87,6 +87,15 @@ module AWSDriver
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
+
def load_env_variables
|
91
|
+
if ENV["AWS_ACCESS_KEY_ID"] && ENV["AWS_SECRET_ACCESS_KEY"]
|
92
|
+
@credentials["default"] = {
|
93
|
+
aws_access_key_id: ENV["AWS_ACCESS_KEY_ID"],
|
94
|
+
aws_secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"]
|
95
|
+
}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
90
99
|
def load_default
|
91
100
|
config_file = ENV['AWS_CONFIG_FILE'] || File.expand_path('~/.aws/config')
|
92
101
|
credentials_file = ENV['AWS_CREDENTIAL_FILE'] || File.expand_path('~/.aws/credentials')
|
@@ -97,6 +106,9 @@ module AWSDriver
|
|
97
106
|
load_inis(config_file)
|
98
107
|
end
|
99
108
|
end
|
109
|
+
if @credentials.size == 0
|
110
|
+
load_env_variables
|
111
|
+
end
|
100
112
|
end
|
101
113
|
|
102
114
|
def self.method_missing(name, *args, &block)
|
@@ -28,7 +28,13 @@ require 'base64'
|
|
28
28
|
|
29
29
|
# loads the entire aws-sdk
|
30
30
|
AWS.eager_autoload!
|
31
|
-
AWS_V2_SERVICES = {
|
31
|
+
AWS_V2_SERVICES = {
|
32
|
+
"EC2" => "ec2",
|
33
|
+
"Route53" => "route53",
|
34
|
+
"S3" => "s3",
|
35
|
+
"ElasticLoadBalancing" => "elb",
|
36
|
+
"IAM" => "iam",
|
37
|
+
}
|
32
38
|
Aws.eager_autoload!(:services => AWS_V2_SERVICES.keys)
|
33
39
|
|
34
40
|
# Need to load the resources after the SDK because `aws_sdk_types` can mess
|
@@ -53,6 +59,24 @@ class Resource
|
|
53
59
|
end
|
54
60
|
end
|
55
61
|
|
62
|
+
require 'chef/provider/load_balancer'
|
63
|
+
class Chef
|
64
|
+
class Provider
|
65
|
+
class LoadBalancer
|
66
|
+
# We override this so we can specify a machine name as `i-123456`
|
67
|
+
# This is totally a hack until we move away from base resources
|
68
|
+
def get_machine_spec!(machine_name)
|
69
|
+
if machine_name =~ /^i-[a-f0-9]{8}$/
|
70
|
+
Struct.new(:name, :reference).new(machine_name, {'instance_id' => machine_name})
|
71
|
+
else
|
72
|
+
Chef::Log.debug "Getting machine spec for #{machine_name}"
|
73
|
+
Provisioning.chef_managed_entry_store(new_resource.chef_server).get!(:machine, machine_name)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
56
80
|
Chef::Provider::Machine.additional_machine_option_keys << :aws_tags
|
57
81
|
Chef::Provider::MachineImage.additional_image_option_keys << :aws_tags
|
58
82
|
Chef::Provider::LoadBalancer.additional_lb_option_keys << :aws_tags
|
@@ -66,7 +90,7 @@ module AWSDriver
|
|
66
90
|
include Chef::Mixin::ShellOut
|
67
91
|
include Chef::Mixin::DeepMerge
|
68
92
|
|
69
|
-
attr_reader :aws_config
|
93
|
+
attr_reader :aws_config, :aws_config_2
|
70
94
|
|
71
95
|
# URL scheme:
|
72
96
|
# aws:profilename:region
|
@@ -97,7 +121,7 @@ module AWSDriver
|
|
97
121
|
# Right now we are supporting both V1 and V2, so we create 2 config sets
|
98
122
|
credentials2 = Credentials2.new(:profile_name => profile_name)
|
99
123
|
Chef::Config.chef_provisioning ||= {}
|
100
|
-
|
124
|
+
@aws_config_2 = {
|
101
125
|
credentials: credentials2.get_credentials,
|
102
126
|
region: region || ENV["AWS_DEFAULT_REGION"] || credentials[:region],
|
103
127
|
# TODO when we get rid of V1 replace the credentials class with something that knows how
|
@@ -105,7 +129,27 @@ module AWSDriver
|
|
105
129
|
:http_proxy => credentials[:proxy_uri] || nil,
|
106
130
|
logger: Chef::Log.logger,
|
107
131
|
retry_limit: Chef::Config.chef_provisioning[:aws_retry_limit] || 5
|
108
|
-
|
132
|
+
}
|
133
|
+
|
134
|
+
driver = self
|
135
|
+
Chef::Resource::Machine.send(:define_method, :aws_object) do
|
136
|
+
resource = Chef::Resource::AwsInstance.new(name, nil)
|
137
|
+
resource.driver driver
|
138
|
+
resource.managed_entry_store Chef::Provisioning.chef_managed_entry_store
|
139
|
+
resource.aws_object
|
140
|
+
end
|
141
|
+
Chef::Resource::MachineImage.send(:define_method, :aws_object) do
|
142
|
+
resource = Chef::Resource::AwsImage.new(name, nil)
|
143
|
+
resource.driver driver
|
144
|
+
resource.managed_entry_store Chef::Provisioning.chef_managed_entry_store
|
145
|
+
resource.aws_object
|
146
|
+
end
|
147
|
+
Chef::Resource::LoadBalancer.send(:define_method, :aws_object) do
|
148
|
+
resource = Chef::Resource::AwsLoadBalancer.new(name, nil)
|
149
|
+
resource.driver driver
|
150
|
+
resource.managed_entry_store Chef::Provisioning.chef_managed_entry_store
|
151
|
+
resource.aws_object
|
152
|
+
end
|
109
153
|
end
|
110
154
|
|
111
155
|
def self.canonicalize_url(driver_url, config)
|
@@ -141,7 +185,10 @@ module AWSDriver
|
|
141
185
|
updates << " with tags #{lb_options[:aws_tags]}" if lb_options[:aws_tags]
|
142
186
|
|
143
187
|
action_handler.perform_action updates do
|
144
|
-
|
188
|
+
# IAM says the server certificate exists, but ELB throws this error
|
189
|
+
Chef::Provisioning::AWSDriver::AWSProvider.retry_with_backoff(AWS::ELB::Errors::CertificateNotFound) do
|
190
|
+
actual_elb = elb.load_balancers.create(lb_spec.name, lb_options)
|
191
|
+
end
|
145
192
|
|
146
193
|
lb_spec.reference = {
|
147
194
|
'driver_version' => Chef::Provisioning::AWSDriver::VERSION,
|
@@ -157,22 +204,9 @@ module AWSDriver
|
|
157
204
|
end
|
158
205
|
|
159
206
|
# TODO: refactor this whole giant method into many smaller method calls
|
160
|
-
# TODO if we update scheme, we don't need to run any of the other updates.
|
161
|
-
# Also, if things aren't specified (such as machines / listeners), we
|
162
|
-
# need to grab them from the actual load balancer so we don't lose them.
|
163
|
-
# i.e. load_balancer 'blah' do
|
164
|
-
# lb_options: { scheme: 'other_scheme' }
|
165
|
-
# end
|
166
|
-
# TODO we will leak the actual_elb if we fail to finish creating it
|
167
|
-
# Update scheme - scheme is immutable once set, so if it is changing we need to delete the old
|
168
|
-
# ELB and create a new one
|
169
207
|
if lb_options[:scheme] && lb_options[:scheme].downcase != actual_elb.scheme
|
170
|
-
|
171
|
-
|
172
|
-
perform_action.call(desc) do
|
173
|
-
old_elb = actual_elb
|
174
|
-
actual_elb = elb.load_balancers.create(lb_spec.name, lb_options)
|
175
|
-
end
|
208
|
+
# TODO CloudFormation automatically recreates the load_balancer, we should too
|
209
|
+
raise "Scheme is immutable - you need to :destroy and :create the load_balancer to recreated it with the new scheme"
|
176
210
|
end
|
177
211
|
|
178
212
|
# Update security groups
|
@@ -248,12 +282,13 @@ module AWSDriver
|
|
248
282
|
load_balancer_name: actual_elb.name,
|
249
283
|
subnets: attach_subnets
|
250
284
|
)
|
251
|
-
rescue AWS::ELB::Errors::InvalidConfigurationRequest
|
252
|
-
|
285
|
+
rescue AWS::ELB::Errors::InvalidConfigurationRequest => e
|
286
|
+
Chef::Log.error "You cannot currently move from 1 subnet to another in the same availability zone. " +
|
253
287
|
"Amazon does not have an atomic operation which allows this. You must create a new " +
|
254
288
|
"ELB with the correct subnets and move instances into it. Tried to attach subets " +
|
255
289
|
"#{attach_subnets.join(', ')} (availability zones #{enable_zones.join(', ')}) to " +
|
256
290
|
"existing ELB named #{actual_elb.name}"
|
291
|
+
raise e
|
257
292
|
end
|
258
293
|
end
|
259
294
|
end
|
@@ -591,11 +626,11 @@ EOD
|
|
591
626
|
class_eval <<-META
|
592
627
|
|
593
628
|
def #{short_name}_client
|
594
|
-
@#{short_name}_client ||= ::Aws::#{load_name}::Client.new
|
629
|
+
@#{short_name}_client ||= ::Aws::#{load_name}::Client.new(**aws_config_2)
|
595
630
|
end
|
596
631
|
|
597
632
|
def #{short_name}_resource
|
598
|
-
@#{short_name}_resource ||= ::Aws::#{load_name}::Resource.new(#{short_name}_client)
|
633
|
+
@#{short_name}_resource ||= ::Aws::#{load_name}::Resource.new(**(aws_config_2.merge({client: #{short_name}_client})))
|
599
634
|
end
|
600
635
|
|
601
636
|
META
|
@@ -621,10 +656,6 @@ EOD
|
|
621
656
|
@s3 ||= AWS::S3.new(config: aws_config)
|
622
657
|
end
|
623
658
|
|
624
|
-
def rds
|
625
|
-
@rds ||= AWS::RDS.new(config: aws_config)
|
626
|
-
end
|
627
|
-
|
628
659
|
def sns
|
629
660
|
@sns ||= AWS::SNS.new(config: aws_config)
|
630
661
|
end
|
@@ -697,9 +728,6 @@ EOD
|
|
697
728
|
Chef::Log.debug('No key specified, generating a default one...')
|
698
729
|
bootstrap_options[:key_name] = default_aws_keypair(action_handler, machine_spec)
|
699
730
|
end
|
700
|
-
if bootstrap_options[:iam_instance_profile] && bootstrap_options[:iam_instance_profile].is_a?(String)
|
701
|
-
bootstrap_options[:iam_instance_profile] = {name: bootstrap_options[:iam_instance_profile]}
|
702
|
-
end
|
703
731
|
if bootstrap_options[:user_data]
|
704
732
|
bootstrap_options[:user_data] = Base64.encode64(bootstrap_options[:user_data])
|
705
733
|
end
|
@@ -727,6 +755,12 @@ EOD
|
|
727
755
|
|
728
756
|
bootstrap_options = AWSResource.lookup_options(bootstrap_options, managed_entry_store: machine_spec.managed_entry_store, driver: self)
|
729
757
|
|
758
|
+
# We do this after the lookup_options because we need the aws_iam_instance_profile resource to
|
759
|
+
# only be passed a String during resource lookup, not `{name: ...}`
|
760
|
+
if bootstrap_options[:iam_instance_profile] && bootstrap_options[:iam_instance_profile].is_a?(String)
|
761
|
+
bootstrap_options[:iam_instance_profile] = {name: bootstrap_options[:iam_instance_profile]}
|
762
|
+
end
|
763
|
+
|
730
764
|
# In the migration from V1 to V2 we still support associate_public_ip_address at the top level
|
731
765
|
# we do this after the lookup because we have to copy any present subnets, etc. into the
|
732
766
|
# network interfaces block
|
@@ -1007,7 +1041,7 @@ EOD
|
|
1007
1041
|
image ||= image_for(image_spec)
|
1008
1042
|
time_elapsed = 0
|
1009
1043
|
sleep_time = 10
|
1010
|
-
max_wait_time = 300
|
1044
|
+
max_wait_time = Chef::Config.chef_provisioning[:image_max_wait_time] || 300
|
1011
1045
|
if !yield(image)
|
1012
1046
|
action_handler.report_progress "waiting for #{image_spec.name} (#{image.id} on #{driver_url}) to be ready ..."
|
1013
1047
|
while time_elapsed < max_wait_time && !yield(image)
|
@@ -1030,8 +1064,7 @@ EOD
|
|
1030
1064
|
|
1031
1065
|
def wait_until_machine(action_handler, machine_spec, output_msg, instance=nil, &block)
|
1032
1066
|
instance ||= instance_for(machine_spec)
|
1033
|
-
|
1034
|
-
max_attempts = 12
|
1067
|
+
max_attempts = ((Chef::Config.chef_provisioning[:machine_max_wait_time] || 120) / 10).floor
|
1035
1068
|
delay = 10
|
1036
1069
|
log_progress = Proc.new do |attempts, response|
|
1037
1070
|
action_handler.report_progress "been waiting #{delay*attempts}/#{delay*max_attempts} -- sleeping #{delay} seconds for #{machine_spec.name} (#{instance.id} on #{driver_url}) to #{output_msg} ..."
|
@@ -1054,7 +1087,7 @@ EOD
|
|
1054
1087
|
instance = instance_for(machine_spec)
|
1055
1088
|
time_elapsed = 0
|
1056
1089
|
sleep_time = 10
|
1057
|
-
max_wait_time = 120
|
1090
|
+
max_wait_time = Chef::Config.chef_provisioning[:machine_max_wait_time] || 120
|
1058
1091
|
transport = transport_for(machine_spec, machine_options, instance)
|
1059
1092
|
unless transport.available?
|
1060
1093
|
if action_handler.should_perform_actions
|
@@ -1178,12 +1211,24 @@ EOD
|
|
1178
1211
|
end
|
1179
1212
|
|
1180
1213
|
def create_instance_and_reference(bootstrap_options, action_handler, machine_spec, machine_options)
|
1181
|
-
instance =
|
1214
|
+
instance = nil
|
1215
|
+
# IAM says the instance profile is ready, but EC2 doesn't think it is
|
1216
|
+
# Not using retry_with_backoff here because we need to match on a string
|
1217
|
+
Retryable.retryable(
|
1218
|
+
:tries => 10,
|
1219
|
+
:sleep => lambda { |n| [2**n, 16].min },
|
1220
|
+
:on => ::Aws::EC2::Errors::InvalidParameterValue,
|
1221
|
+
:matching => /Invalid IAM Instance Profile name/
|
1222
|
+
) do |retries, exception|
|
1223
|
+
Chef::Log.debug("Instance creation InvalidParameterValue exception is #{exception.inspect}")
|
1224
|
+
instance = ec2_resource.create_instances(bootstrap_options.to_hash)[0]
|
1225
|
+
end
|
1226
|
+
|
1182
1227
|
# Make sure the instance is ready to be tagged
|
1183
1228
|
instance.wait_until_exists
|
1184
1229
|
|
1185
1230
|
# Sometimes tagging fails even though the instance 'exists'
|
1186
|
-
|
1231
|
+
Chef::Provisioning::AWSDriver::AWSProvider.retry_with_backoff(::Aws::EC2::Errors::InvalidInstanceIDNotFound) do
|
1187
1232
|
instance.create_tags({tags: [{key: "Name", value: machine_spec.name}]})
|
1188
1233
|
end
|
1189
1234
|
if machine_options.has_key?(:source_dest_check)
|
@@ -5,60 +5,73 @@ module Provisioning
|
|
5
5
|
module AWSDriver
|
6
6
|
class SuperLWRP < Chef::Resource::LWRPBase
|
7
7
|
#
|
8
|
-
# Add the :
|
8
|
+
# Add the :default lazy { ... } and :coerce validation_opts to `attribute`
|
9
9
|
#
|
10
|
-
|
11
|
-
|
12
|
-
coerce
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
if self.respond_to?(:properties)
|
11
|
+
# in Chef 12.5+, properties replace attributes and these respond to
|
12
|
+
# coerce and default with a lazy block - no need for overwriting!
|
13
|
+
else
|
14
|
+
def self.attribute(attr_name, validation_opts={})
|
15
|
+
if validation_opts[:default].is_a?(Chef::DelayedEvaluator)
|
16
|
+
lazy_default = validation_opts.delete(:default)
|
17
|
+
end
|
18
|
+
coerce = validation_opts.delete(:coerce)
|
19
|
+
if lazy_default || coerce
|
20
|
+
define_method(attr_name) do |arg=nil|
|
21
|
+
arg = instance_exec(arg, &coerce) if coerce && !arg.nil?
|
16
22
|
|
17
|
-
|
23
|
+
result = set_or_return(attr_name.to_sym, arg, validation_opts)
|
18
24
|
|
19
|
-
|
20
|
-
|
21
|
-
|
25
|
+
if result.nil? && arg.nil?
|
26
|
+
result = instance_eval(&lazy_default) if lazy_default
|
27
|
+
end
|
22
28
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
29
|
+
result
|
30
|
+
end
|
31
|
+
define_method(:"#{attr_name}=") do |arg|
|
32
|
+
if arg.nil?
|
33
|
+
remove_instance_variable(:"@#{arg}")
|
34
|
+
else
|
35
|
+
set_or_return(attr_name.to_sym, arg, validation_opts)
|
36
|
+
end
|
30
37
|
end
|
38
|
+
else
|
39
|
+
super
|
31
40
|
end
|
32
|
-
else
|
33
|
-
super
|
34
41
|
end
|
35
|
-
end
|
36
42
|
|
37
|
-
|
38
|
-
|
39
|
-
|
43
|
+
# Below chef 12.5 you cannot do `default lazy: { ... }` - this adds that
|
44
|
+
def self.lazy(&block)
|
45
|
+
Chef::DelayedEvaluator.new(&block)
|
46
|
+
end
|
40
47
|
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
48
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
49
|
+
# copy from Chef 12.5 params_validate.rb at http://redirx.me/?t35q.
|
50
|
+
if !method_defined?(:_pv_is)
|
51
|
+
def _pv_is(opts, key, to_be, raise_error: true)
|
52
|
+
return true if !opts.has_key?(key.to_s) && !opts.has_key?(key.to_sym)
|
53
|
+
value = _pv_opts_lookup(opts, key)
|
54
|
+
to_be = [ to_be ].flatten(1)
|
55
|
+
to_be.each do |tb|
|
56
|
+
case tb
|
57
|
+
when Proc
|
58
|
+
return true if instance_exec(value, &tb)
|
59
|
+
when Property
|
60
|
+
validate(opts, { key => tb.validation_options })
|
61
|
+
return true
|
62
|
+
else
|
63
|
+
return true if tb === value
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
if raise_error
|
68
|
+
raise ::Chef::Exceptions::ValidationFailed, "Option #{key} must be one of: #{to_be.join(", ")}! You passed #{value.inspect}."
|
69
|
+
else
|
70
|
+
false
|
71
|
+
end
|
72
|
+
end
|
53
73
|
end
|
54
74
|
end
|
55
|
-
def emit_cloned_resource_warning; end
|
56
|
-
def emit_harmless_cloning_debug; end
|
57
75
|
end
|
58
|
-
|
59
|
-
# Chef 12.2 changed `load_prior_resource` logic to be in the Chef::ResourceBuilder class
|
60
|
-
# but that class only exists in 12.2 and up
|
61
|
-
if defined? Chef::ResourceBuilder
|
62
|
-
# Ruby 2.0.0 has prepend as a protected method
|
63
|
-
Chef::ResourceBuilder.send(:prepend, NoResourceCloning)
|
76
|
+
end
|
64
77
|
end
|
@@ -47,7 +47,7 @@ class Chef::Resource::AwsDhcpOptions < Chef::Provisioning::AWSDriver::AWSResourc
|
|
47
47
|
#
|
48
48
|
attribute :netbios_node_type, kind_of: Integer
|
49
49
|
|
50
|
-
attribute :dhcp_options_id, kind_of: String, aws_id_attribute: true,
|
50
|
+
attribute :dhcp_options_id, kind_of: String, aws_id_attribute: true, default: lazy {
|
51
51
|
name =~ /^dopt-[a-f0-9]{8}$/ ? name : nil
|
52
52
|
}
|
53
53
|
|
@@ -19,7 +19,7 @@ class Chef::Resource::AwsEbsVolume < Chef::Provisioning::AWSDriver::AWSResourceW
|
|
19
19
|
attribute :encrypted, kind_of: [ TrueClass, FalseClass ]
|
20
20
|
attribute :device, kind_of: String
|
21
21
|
|
22
|
-
attribute :volume_id, kind_of: String, aws_id_attribute: true,
|
22
|
+
attribute :volume_id, kind_of: String, aws_id_attribute: true, default: lazy {
|
23
23
|
name =~ /^vol-[a-f0-9]{8}$/ ? name : nil
|
24
24
|
}
|
25
25
|
|
@@ -26,7 +26,7 @@ class Chef::Resource::AwsEipAddress < Chef::Provisioning::AWSDriver::AWSResource
|
|
26
26
|
# ```
|
27
27
|
#
|
28
28
|
attribute :public_ip, kind_of: String, aws_id_attribute: true, coerce: proc { |v| IPAddr.new(v); v },
|
29
|
-
|
29
|
+
default: lazy {
|
30
30
|
begin
|
31
31
|
IPAddr.new(name)
|
32
32
|
name
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'chef/provisioning/aws_driver/aws_resource'
|
2
|
+
|
3
|
+
#
|
4
|
+
# An AWS IAM instance profile, a container for an IAM role that you can use to
|
5
|
+
# pass role information to an EC2 instance when the instance starts..
|
6
|
+
#
|
7
|
+
# `name` is unique for an AWS account.
|
8
|
+
#
|
9
|
+
# API documentation for the AWS Ruby SDK for IAM instance profiles (and the object returned from `aws_object`) can be found here:
|
10
|
+
#
|
11
|
+
# - http://docs.aws.amazon.com/sdkforruby/api/Aws/IAM/InstanceProfile.html
|
12
|
+
#
|
13
|
+
class Chef::Resource::AwsIamInstanceProfile < Chef::Provisioning::AWSDriver::AWSResource
|
14
|
+
aws_sdk_type ::Aws::IAM::InstanceProfile
|
15
|
+
|
16
|
+
#
|
17
|
+
# The name of the instance profile to create.
|
18
|
+
#
|
19
|
+
attribute :name, kind_of: String, name_attribute: true
|
20
|
+
|
21
|
+
#
|
22
|
+
# The path to the instance profile. For more information about paths, see http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html
|
23
|
+
#
|
24
|
+
attribute :path, kind_of: String
|
25
|
+
|
26
|
+
attribute :role, kind_of: [ String, AwsIamRole, ::Aws::IAM::Role]
|
27
|
+
|
28
|
+
def aws_object
|
29
|
+
result = driver.iam_resource.instance_profile(name)
|
30
|
+
result && result.exists? ? result : nil
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|