sparkle_formation 2.1.4 → 2.1.6

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: 9128303439223716fec4b197bdf3c2e12a7a4f15
4
- data.tar.gz: cc6265ec22c8947567394f4903b7d7ae33702817
3
+ metadata.gz: b90504a372c30016cb3ac38668586571b7df605b
4
+ data.tar.gz: 5e2dddc009e43e3e107f884a75b02d0c9cd9c261
5
5
  SHA512:
6
- metadata.gz: 728d1c57b1502d226e25143d659a21deba9f886ac549f6c2d4c693c00f9098008769a4860e31d19f2f31ef3313786d36525ec6007ef9f89ae75a193df9cf0735
7
- data.tar.gz: 45116831add1bf3862729f02dd93f2900de3969164402d96231c54ced176bcdd21288a295066da3c612296ece1bcde19d2da48d39c8a6cb04e29863768cbde32
6
+ metadata.gz: 222b26eb1dd56868023c9b9360dca1186825caa6450f3966019d9c0869e93f2ebde99924529e51cf48e8bf2f7f6ae6ee8e8681c99a1f09b55870d7be374e4766
7
+ data.tar.gz: 28f754b8b048d941ea844c5e3e5b605a0a2b5a8844ad9d915d16fd61ddd0007ca72203824ec50bcd721fe9ea4f8bf18bac2c294bef420016188bf73c6ef59152
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # v2.1.6
2
+ * Update builtin resource lists (#156)
3
+ * Refactor internal template composition (#158)
4
+
1
5
  # v2.1.4
2
6
  * Fix struct value storage within internal table (#147)
3
7
 
data/docs/anatomy.md CHANGED
@@ -145,7 +145,7 @@ SparkleFormation.new(:template) do
145
145
  creator_is_spox equals!(ref!(:creator), 'spox')
146
146
  end
147
147
  dynamic!(:ec2_instance, :fubar) do
148
- on_condition :creator_is_spox
148
+ on_condition! :creator_is_spox
149
149
  end
150
150
  end
151
151
  ~~~
@@ -309,6 +309,28 @@ SparkleFormation.new(:instance_stack) do
309
309
  end
310
310
  ~~~
311
311
 
312
+ Additional parameters can be passed into registry methods
313
+
314
+ ~~~ruby
315
+ SfnRegistry.register(:instance_size_default) do |args={}|
316
+ args[:class] + "." + args[:size]
317
+ end
318
+ ~~~
319
+
320
+ And references in your template
321
+
322
+ ~~~ruby
323
+ SparkleFormation.new(:instance_stack) do
324
+ parameters.instance_size do
325
+ type 'String'
326
+ allowed_values registry!(:instance_sizes)
327
+ default registry!(:instance_size_default, :class => 'm3', :size => 'large')
328
+ end
329
+ end
330
+ ~~~
331
+
332
+ InstanceSize will then be given a default value of 'm3.large'
333
+
312
334
  ### Templates
313
335
 
314
336
  Templates are the files that pull all the building blocks together to produce
@@ -23,6 +23,7 @@ require 'attribute_struct'
23
23
  # Unicorns and rainbows
24
24
  class SparkleFormation
25
25
  autoload :Aws, 'sparkle_formation/aws'
26
+ autoload :Composition, 'sparkle_formation/composition'
26
27
  autoload :Error, 'sparkle_formation/error'
27
28
  autoload :FunctionStruct, 'sparkle_formation/function_struct'
28
29
  autoload :Provider, 'sparkle_formation/provider'
@@ -0,0 +1,179 @@
1
+ require 'sparkle_formation'
2
+
3
+ class SparkleFormation
4
+ # Internal template composition
5
+ class Composition
6
+
7
+ # Component item of composition
8
+ Component = Struct.new('Component', :origin, :key, :block) do
9
+ def key
10
+ self[:key].to_s
11
+ end
12
+ end
13
+
14
+ # Override item of composition
15
+ Override = Struct.new('Override', :origin, :args, :block)
16
+
17
+ # @return [SparkleFormation] owner of composition
18
+ attr_reader :origin
19
+
20
+ # Create a new composition
21
+ #
22
+ # @param origin [SparkleFormation] owner of composition
23
+ # @param args [Hash]
24
+ # @option args [Array<Component>] :components seed components for composition
25
+ # @option args [Array<Override>] :overrides seed overrides for composition
26
+ # @return [self]
27
+ def initialize(origin, args={})
28
+ unless(origin.is_a?(SparkleFormation))
29
+ raise TypeError.new 'Composition requires `SparkleFormation` instance as origin. ' \
30
+ "Received origin type `#{origin.class}`."
31
+ end
32
+ @origin = origin
33
+ @components_list = []
34
+ @overrides_list = []
35
+ seed_value(args[:overrides], Override).each do |item|
36
+ add_override(item)
37
+ end
38
+ seed_value(args[:components], [Component, Override]).each do |item|
39
+ add_component(item)
40
+ end
41
+ end
42
+
43
+ # @return [Array<Component, Override>]
44
+ def components
45
+ @components_list.dup.freeze
46
+ end
47
+
48
+ # @return [Array<Override>]
49
+ def overrides
50
+ @overrides_list.dup.freeze
51
+ end
52
+
53
+ # Provides the full list of items in order
54
+ #
55
+ # @return [Array<Component, Override>]
56
+ def composite
57
+ [components + overrides].flatten.freeze
58
+ end
59
+
60
+ # Add an existing component
61
+ #
62
+ # @param item [Component, Override]
63
+ # @param location [Symbol] :prepend or :append (defaults to :append)
64
+ # @return [self]
65
+ def add_component(item, location=:append)
66
+ if(item.respond_to?(:key) && component_keys.include?(item.key))
67
+ # do nothing
68
+ else
69
+ case location
70
+ when :append
71
+ components_list.push(item)
72
+ when :prepend
73
+ components_list.unshift(item)
74
+ else
75
+ raise ArgumentError.new 'Unknown addition location provided. Valid: `:append, :prepend`. ' \
76
+ "Received: `#{location.inspect}`"
77
+ end
78
+ end
79
+ self
80
+ end
81
+
82
+ # Add an existing override
83
+ #
84
+ # @param item [Override]
85
+ # @param location [Symbol] :prepend or :append (defaults to :append)
86
+ # @return [self]
87
+ def add_override(item, location=:append)
88
+ case location
89
+ when :append
90
+ overrides_list.push(item)
91
+ when :prepend
92
+ overrides_list.unshift(item)
93
+ else
94
+ raise ArgumentError.new 'Unknown addition location provided. Valid: ' \
95
+ "`:append, :prepend`. Received: `#{location.inspect}`"
96
+ end
97
+ self
98
+ end
99
+
100
+ # Add a new component
101
+ #
102
+ # @param key [Symbol, String] component identifier
103
+ # @param location [Symbol] :prepend or :append (defaults to :append)
104
+ # @yield component block (optional)
105
+ # @return [self]
106
+ def new_component(key, location=:append, &block)
107
+ comp = Component.new(origin, key, block)
108
+ add_component(comp, location)
109
+ self
110
+ end
111
+
112
+ # Add a new override
113
+ #
114
+ # @param args [Hash] local state provided to override
115
+ # @param location [Symbol] :prepend or :append (defaults to :append)
116
+ # @yield override block
117
+ # @return [self]
118
+ def new_override(args={}, location=:append, &block)
119
+ if(args.is_a?(Symbol))
120
+ location = args
121
+ args = {}
122
+ end
123
+ ovr = Override.new(origin, args, block)
124
+ add_override(ovr, location)
125
+ self
126
+ end
127
+
128
+ # Iterate full composition
129
+ #
130
+ # @yield block to execute each item
131
+ # @yieldparam [Component, Override]
132
+ # @return [self]
133
+ def each
134
+ if(block_given?)
135
+ composite.each do |item|
136
+ yield item
137
+ end
138
+ end
139
+ self
140
+ end
141
+
142
+ protected
143
+
144
+ # @return [Array<String, Symbol>]
145
+ def component_keys
146
+ components.map do |item|
147
+ item.respond_to?(:key) ? item.key : nil
148
+ end.compact
149
+ end
150
+
151
+ # If items list provided, validate types and return
152
+ # copy of list. If no list provided, return new list.
153
+ #
154
+ # @param items [Array]
155
+ # @param type [Class]
156
+ # @return [Array]
157
+ def seed_value(items, type)
158
+ type = [type].flatten.compact
159
+ if(items)
160
+ items.each do |item|
161
+ valid_item = type.any? do |klass|
162
+ item.is_a?(klass)
163
+ end
164
+ unless(valid_item)
165
+ raise TypeError.new "Invalid type encountered within collection `#{item.class}`. " \
166
+ "Expected `#{type.map(&:to_s).join('`, `')}`."
167
+ end
168
+ end
169
+ items.dup
170
+ else
171
+ []
172
+ end
173
+ end
174
+
175
+ attr_reader :components_list, :overrides_list
176
+
177
+ end
178
+
179
+ end
@@ -265,6 +265,153 @@
265
265
  },
266
266
  "path": "aws-resource-lambda-eventsourcemapping.html"
267
267
  },
268
+ "AWS::EMR::Cluster": {
269
+ "properties": [
270
+ "AdditionalInfo",
271
+ "Applications",
272
+ "BootstrapActions",
273
+ "Configurations",
274
+ "Instances",
275
+ "JobFlowRole",
276
+ "LogUri",
277
+ "Name",
278
+ "ReleaseLabel",
279
+ "ServiceRole",
280
+ "Tags",
281
+ "VisibleToAllUsers"
282
+ ],
283
+ "full_properties": {
284
+ "AdditionalInfo": {
285
+ "description": "Additional features that you want to select.",
286
+ "required": false,
287
+ "type": "Unknown",
288
+ "update_causes": "replacement"
289
+ },
290
+ "Applications": {
291
+ "description": "The software applications to deploy on the cluster, and the arguments that Amazon EMR passes to those applications.",
292
+ "required": false,
293
+ "type": "Array",
294
+ "update_causes": "replacement"
295
+ },
296
+ "BootstrapActions": {
297
+ "description": "A list of bootstrap actions that Amazon EMR runs before starting applications on the cluster.",
298
+ "required": false,
299
+ "type": "Array",
300
+ "update_causes": "replacement"
301
+ },
302
+ "Configurations": {
303
+ "description": "The software configuration of the Amazon EMR cluster.",
304
+ "required": false,
305
+ "type": "Array",
306
+ "update_causes": "replacement"
307
+ },
308
+ "Instances": {
309
+ "description": "Configures the EC2 instances that will run jobs in the Amazon EMR cluster.",
310
+ "required": true,
311
+ "type": "Unknown",
312
+ "update_causes": "replacement"
313
+ },
314
+ "JobFlowRole": {
315
+ "description": "An AWS Identity and Access Management (IAM) role for an Amazon EMR cluster. All EC2 instances in the cluster assume this role, which instances use to access AWS services and resources to complete a job. For more information, see Configure IAM Roles for Amazon EMR in the Amazon Elastic MapReduce Management Guide.",
316
+ "required": true,
317
+ "type": "String",
318
+ "update_causes": "replacement"
319
+ },
320
+ "LogUri": {
321
+ "description": "An S3 bucket location to which Amazon EMR writes logs files from a job flow. If you don't specify a value, Amazon EMR doesn't write any log files.",
322
+ "required": false,
323
+ "type": "String",
324
+ "update_causes": "replacement"
325
+ },
326
+ "Name": {
327
+ "description": "A name for the Amazon EMR cluster.",
328
+ "required": true,
329
+ "type": "String",
330
+ "update_causes": "replacement"
331
+ },
332
+ "ReleaseLabel": {
333
+ "description": "The Amazon EMR software release label. A release is a set of software applications and components that you can install and configure on an Amazon EMR cluster. For more information, see About Amazon EMR Releases in the Amazon Elastic MapReduce Release Guide.",
334
+ "required": false,
335
+ "type": "String",
336
+ "update_causes": "replacement"
337
+ },
338
+ "ServiceRole": {
339
+ "description": "The IAM role that Amazon EMR assumes to access AWS resources on your behalf. For more information, see Configure IAM Roles for Amazon EMR in the Amazon Elastic MapReduce Management Guide.",
340
+ "required": true,
341
+ "type": "String",
342
+ "update_causes": "replacement"
343
+ },
344
+ "Tags": {
345
+ "description": "An arbitrary set of tags (key–value pairs) to help you identify the Amazon EMR cluster.",
346
+ "required": false,
347
+ "type": "Unknown",
348
+ "update_causes": "none"
349
+ },
350
+ "VisibleToAllUsers": {
351
+ "description": "Indicates whether the instances in the cluster are visible to all IAM users in the AWS account. If you specify true, all IAM users can view and (if they have permissions) manage the instances. If you specify false, only the IAM user that created the cluster can view and manage it. By default, AWS CloudFormation sets this property to false.",
352
+ "required": false,
353
+ "type": "Boolean",
354
+ "update_causes": "none"
355
+ }
356
+ },
357
+ "path": "aws-resource-emr-cluster.html"
358
+ },
359
+ "AWS::Elasticsearch::Domain": {
360
+ "properties": [
361
+ "AccessPolicies",
362
+ "AdvancedOptions",
363
+ "DomainName",
364
+ "EBSOptions",
365
+ "ElasticsearchClusterConfig",
366
+ "SnapshotOptions",
367
+ "Tags"
368
+ ],
369
+ "full_properties": {
370
+ "AccessPolicies": {
371
+ "description": "An AWS Identity and Access Management (IAM) policy document that specifies who can access the Amazon ES domain and their permissions. For more information, see Configuring Access Policies in the Amazon Elasticsearch Service Developer Guide.",
372
+ "required": false,
373
+ "type": "Unknown",
374
+ "update_causes": "none"
375
+ },
376
+ "AdvancedOptions": {
377
+ "description": "Additional options to specify for the Amazon ES domain. For more information, see Configuring Advanced Options in the Amazon Elasticsearch Service Developer Guide.",
378
+ "required": false,
379
+ "type": "Unknown",
380
+ "update_causes": "replacement"
381
+ },
382
+ "DomainName": {
383
+ "description": "A name for the Amazon ES domain. If you don't specify a name, AWS CloudFormation generates a unique physical ID and uses that ID for the domain name. For more information, see Name Type.",
384
+ "required": true,
385
+ "type": "Unknown",
386
+ "update_causes": "replacement"
387
+ },
388
+ "EBSOptions": {
389
+ "description": "The configurations of Amazon Elastic Block Store (Amazon EBS) volumes that are attached to data nodes in the Amazon ES domain. For more information, see Configuring EBS-based Storage in the Amazon Elasticsearch Service Developer Guide.",
390
+ "required": false,
391
+ "type": "Unknown",
392
+ "update_causes": "none"
393
+ },
394
+ "ElasticsearchClusterConfig": {
395
+ "description": "The cluster configuration for the Amazon ES domain. You can specify options such as the instance type and the number of instances. For more information, see Configuring Amazon ES Domains in the Amazon Elasticsearch Service Developer Guide.",
396
+ "required": false,
397
+ "type": "Unknown",
398
+ "update_causes": "none"
399
+ },
400
+ "SnapshotOptions": {
401
+ "description": "The automated snapshot configuration for the Amazon ES domain indices.",
402
+ "required": false,
403
+ "type": "Unknown",
404
+ "update_causes": "none"
405
+ },
406
+ "Tags": {
407
+ "description": "An arbitrary set of tags (key–value pairs) to associate with the Amazon ES domain.",
408
+ "required": false,
409
+ "type": "Unknown",
410
+ "update_causes": "none"
411
+ }
412
+ },
413
+ "path": "aws-resource-elasticsearch-domain.html"
414
+ },
268
415
  "AWS::WAF::IPSet": {
269
416
  "properties": [
270
417
  "IPSetDescriptors",
@@ -855,12 +1002,14 @@
855
1002
  "DBSubnetGroupName",
856
1003
  "Engine",
857
1004
  "EngineVersion",
1005
+ "KmsKeyId",
858
1006
  "MasterUsername",
859
1007
  "MasterUserPassword",
860
1008
  "Port",
861
1009
  "PreferredBackupWindow",
862
1010
  "PreferredMaintenanceWindow",
863
1011
  "SnapshotIdentifier",
1012
+ "StorageEncrypted",
864
1013
  "Tags",
865
1014
  "VpcSecurityGroupIds"
866
1015
  ],
@@ -907,6 +1056,12 @@
907
1056
  "type": "String",
908
1057
  "update_causes": "replacement"
909
1058
  },
1059
+ "KmsKeyId": {
1060
+ "description": "The Amazon Resource Name (ARN) of the AWS Key Management Service master key that is used to encrypt the database instances in the DB cluster, such as arn:aws:kms:us-east-1:012345678910:key/abcd1234-a123-456a-a12b-a123b4cd56ef. If you enable the StorageEncrypted property but don't specify this property, the default master key is used. If you specify this property, you must set the StorageEncrypted property to true.",
1061
+ "required": false,
1062
+ "type": "String",
1063
+ "update_causes": "replacement"
1064
+ },
910
1065
  "MasterUsername": {
911
1066
  "description": "The master user name for the DB instance.",
912
1067
  "required": false,
@@ -943,6 +1098,12 @@
943
1098
  "type": "String",
944
1099
  "update_causes": "replacement"
945
1100
  },
1101
+ "StorageEncrypted": {
1102
+ "description": "Indicates whether the DB instances in the cluster are encrypted.",
1103
+ "required": false,
1104
+ "type": "Boolean",
1105
+ "update_causes": "replacement"
1106
+ },
946
1107
  "Tags": {
947
1108
  "description": "The tags that you want to attach to this DB cluster.",
948
1109
  "required": false,
@@ -1308,6 +1469,41 @@
1308
1469
  },
1309
1470
  "path": "aws-properties-elasticache-parameter-group.html"
1310
1471
  },
1472
+ "AWS::EMR::Step": {
1473
+ "properties": [
1474
+ "ActionOnFailure",
1475
+ "HadoopJarStep",
1476
+ "JobFlowId",
1477
+ "Name"
1478
+ ],
1479
+ "full_properties": {
1480
+ "ActionOnFailure": {
1481
+ "description": "The action to take if the job flow step fails. Currently, AWS CloudFormation supports CONTINUE and CONTINUE_AND_WAIT. For more information, see Managing Cluster Termination in the Amazon Elastic MapReduce Management Guide.",
1482
+ "required": true,
1483
+ "type": "String",
1484
+ "update_causes": "replacement"
1485
+ },
1486
+ "HadoopJarStep": {
1487
+ "description": "The JAR file that includes the main function that Amazon EMR executes.",
1488
+ "required": true,
1489
+ "type": "Unknown",
1490
+ "update_causes": "replacement"
1491
+ },
1492
+ "JobFlowId": {
1493
+ "description": "The ID of a cluster in which you want to run this job flow step.",
1494
+ "required": true,
1495
+ "type": "String",
1496
+ "update_causes": "replacement"
1497
+ },
1498
+ "Name": {
1499
+ "description": "A name for the job flow step.",
1500
+ "required": true,
1501
+ "type": "String",
1502
+ "update_causes": "replacement"
1503
+ }
1504
+ },
1505
+ "path": "aws-resource-emr-step.html"
1506
+ },
1311
1507
  "AWS::Lambda::Function": {
1312
1508
  "properties": [
1313
1509
  "Code",
@@ -2865,24 +3061,31 @@
2865
3061
  "DestinationCidrBlock",
2866
3062
  "GatewayId",
2867
3063
  "InstanceId",
3064
+ "NatGatewayId",
2868
3065
  "NetworkInterfaceId",
2869
3066
  "RouteTableId"
2870
3067
  ],
2871
3068
  "full_properties": {
2872
3069
  "DestinationCidrBlock": {
2873
- "description": "The CIDR address block used for the destination match. For example, \"0.0.0.0/0\". Routing decisions are based on the most specific match.",
3070
+ "description": "The CIDR address block used for the destination match. For example, 0.0.0.0/0. Routing decisions are based on the most specific match.",
2874
3071
  "required": true,
2875
3072
  "type": "String",
2876
3073
  "update_causes": "replacement"
2877
3074
  },
2878
3075
  "GatewayId": {
2879
- "description": "The ID of an Internet gateway or virtual private gateway that is attached to your VPC. For example: \"igw-eaad4883\".",
3076
+ "description": "The ID of an Internet gateway or virtual private gateway that is attached to your VPC. For example: igw-eaad4883.",
2880
3077
  "required": false,
2881
3078
  "type": "String",
2882
3079
  "update_causes": "none"
2883
3080
  },
2884
3081
  "InstanceId": {
2885
- "description": "The ID of a NAT instance in your VPC. For example, \"i-1a2b3c4d\".",
3082
+ "description": "The ID of a NAT instance in your VPC. For example, i-1a2b3c4d.",
3083
+ "required": false,
3084
+ "type": "String",
3085
+ "update_causes": "none"
3086
+ },
3087
+ "NatGatewayId": {
3088
+ "description": "The ID of a NAT gateway. For example, nat-0a12bc456789de0fg.",
2886
3089
  "required": false,
2887
3090
  "type": "String",
2888
3091
  "update_causes": "none"
@@ -2987,7 +3190,7 @@
2987
3190
  "update_causes": "interrupt"
2988
3191
  },
2989
3192
  "DBInstanceIdentifier": {
2990
- "description": "A name for the DB instance. If you don't specify a name, AWS CloudFormation generates a unique physical ID and uses that ID for the DB instance. For more information, see Name Type.",
3193
+ "description": "A name for the DB instance. If you specify a name, AWS CloudFormation converts it to lower case. If you don't specify a name, AWS CloudFormation generates a unique physical ID and uses that ID for the DB instance. For more information, see Name Type.",
2991
3194
  "required": false,
2992
3195
  "type": "Unknown",
2993
3196
  "update_causes": "replacement"
@@ -3193,6 +3396,7 @@
3193
3396
  "properties": [
3194
3397
  "NotificationARNs",
3195
3398
  "Parameters",
3399
+ "Tags",
3196
3400
  "TemplateURL",
3197
3401
  "TimeoutInMinutes"
3198
3402
  ],
@@ -3209,6 +3413,12 @@
3209
3413
  "type": "Unknown",
3210
3414
  "update_causes": "interrupt"
3211
3415
  },
3416
+ "Tags": {
3417
+ "description": "An arbitrary set of tags (key–value pairs) to describe this stack.",
3418
+ "required": false,
3419
+ "type": "Unknown",
3420
+ "update_causes": "none"
3421
+ },
3212
3422
  "TemplateURL": {
3213
3423
  "description": "The URL of a template that specifies the stack that you want to create as a resource. The template must be stored on an Amazon S3 bucket, so the URL must have the form: https://s3.amazonaws.com/.../TemplateName.template",
3214
3424
  "required": true,
@@ -3699,6 +3909,69 @@
3699
3909
  },
3700
3910
  "path": "aws-resource-config-configurationrecorder.html"
3701
3911
  },
3912
+ "AWS::EMR::InstanceGroupConfig": {
3913
+ "properties": [
3914
+ "BidPrice",
3915
+ "Configurations",
3916
+ "InstanceCount",
3917
+ "InstanceRole",
3918
+ "InstanceType",
3919
+ "JobFlowId",
3920
+ "Market",
3921
+ "Name"
3922
+ ],
3923
+ "full_properties": {
3924
+ "BidPrice": {
3925
+ "description": "The bid price in USD for each EC2 instance in the instance group when launching instances (nodes) as Spot Instances.",
3926
+ "required": false,
3927
+ "type": "String",
3928
+ "update_causes": "replacement"
3929
+ },
3930
+ "Configurations": {
3931
+ "description": "A list of configurations to apply to this instance group. For more information see, Configuring Applications in the Amazon Elastic MapReduce Release Guide.",
3932
+ "required": false,
3933
+ "type": "Array",
3934
+ "update_causes": "replacement"
3935
+ },
3936
+ "InstanceCount": {
3937
+ "description": "The number of instances to launch in the instance group.",
3938
+ "required": true,
3939
+ "type": "Number",
3940
+ "update_causes": "none"
3941
+ },
3942
+ "InstanceRole": {
3943
+ "description": "The role of the servers in the Amazon EMR cluster, such as TASK. For more information, see Instance Groups in the Amazon Elastic MapReduce Management Guide.",
3944
+ "required": true,
3945
+ "type": "String",
3946
+ "update_causes": "replacement"
3947
+ },
3948
+ "InstanceType": {
3949
+ "description": "The EC2 instance type for all instances in the instance group. For more information, see Instance Configurations in the Amazon Elastic MapReduce Management Guide.",
3950
+ "required": true,
3951
+ "type": "String",
3952
+ "update_causes": "replacement"
3953
+ },
3954
+ "JobFlowId": {
3955
+ "description": "The ID of an Amazon EMR cluster that you want to associate this instance group with.",
3956
+ "required": true,
3957
+ "type": "String",
3958
+ "update_causes": "replacement"
3959
+ },
3960
+ "Market": {
3961
+ "description": "The type of marketplace from which your instances are provisioned into this group, either ON_DEMAND or SPOT. For more information, see Amazon EC2 Purchasing Options.",
3962
+ "required": false,
3963
+ "type": "String",
3964
+ "update_causes": "replacement"
3965
+ },
3966
+ "Name": {
3967
+ "description": "A name for the instance group.",
3968
+ "required": false,
3969
+ "type": "String",
3970
+ "update_causes": "replacement"
3971
+ }
3972
+ },
3973
+ "path": "aws-resource-emr-instancegroupconfig.html"
3974
+ },
3702
3975
  "AWS::Redshift::ClusterSecurityGroupIngress": {
3703
3976
  "properties": [
3704
3977
  "ClusterSecurityGroupName",
@@ -3818,8 +4091,8 @@
3818
4091
  "update_causes": "replacement"
3819
4092
  },
3820
4093
  "Status": {
3821
- "description": "The status of the access key.",
3822
- "required": true,
4094
+ "description": "The status of the access key. By default, AWS CloudFormation sets this property value to Active.",
4095
+ "required": false,
3823
4096
  "type": "String",
3824
4097
  "update_causes": "none"
3825
4098
  },
@@ -3923,6 +4196,27 @@
3923
4196
  },
3924
4197
  "path": "aws-resource-datapipeline-pipeline.html"
3925
4198
  },
4199
+ "AWS::EC2::NatGateway": {
4200
+ "properties": [
4201
+ "AllocationId",
4202
+ "SubnetId"
4203
+ ],
4204
+ "full_properties": {
4205
+ "AllocationId": {
4206
+ "description": "The allocation ID of an Elastic IP address to associate with the NAT gateway. If the Elastic IP address is associated with another resource, you must first disassociate it.",
4207
+ "required": true,
4208
+ "type": "String",
4209
+ "update_causes": "replacement"
4210
+ },
4211
+ "SubnetId": {
4212
+ "description": "The public subnet in which to create the NAT gateway.",
4213
+ "required": true,
4214
+ "type": "String",
4215
+ "update_causes": "replacement"
4216
+ }
4217
+ },
4218
+ "path": "aws-resource-ec2-natgateway.html"
4219
+ },
3926
4220
  "AWS::EC2::VPCGatewayAttachment": {
3927
4221
  "properties": [
3928
4222
  "InternetGatewayId",
@@ -4118,19 +4412,19 @@
4118
4412
  "GlobalSecondaryIndexes": {
4119
4413
  "description": "Global secondary indexes to be created on the table. You can create up to 5 global secondary indexes.",
4120
4414
  "required": false,
4121
- "type": "Unknown",
4415
+ "type": "Array",
4122
4416
  "update_causes": "replacement"
4123
4417
  },
4124
4418
  "KeySchema": {
4125
4419
  "description": "Specifies the attributes that make up the primary key for the table. The attributes in the KeySchema property must also be defined in the AttributeDefinitions property.",
4126
4420
  "required": true,
4127
- "type": "Unknown",
4421
+ "type": "Array",
4128
4422
  "update_causes": "replacement"
4129
4423
  },
4130
4424
  "LocalSecondaryIndexes": {
4131
4425
  "description": "Local secondary indexes to be created on the table. You can create up to 5 local secondary indexes. Each index is scoped to a given hash key value. The size of each hash key can be up to 10 gigabytes.",
4132
4426
  "required": false,
4133
- "type": "Unknown",
4427
+ "type": "Array",
4134
4428
  "update_causes": "replacement"
4135
4429
  },
4136
4430
  "StreamSpecification": {
@@ -4154,6 +4448,27 @@
4154
4448
  },
4155
4449
  "path": "aws-resource-dynamodb-table.html"
4156
4450
  },
4451
+ "AWS::ECR::Repository": {
4452
+ "properties": [
4453
+ "RepositoryName",
4454
+ "RepositoryPolicyText"
4455
+ ],
4456
+ "full_properties": {
4457
+ "RepositoryName": {
4458
+ "description": "A name for the image repository. If you don't specify a name, AWS CloudFormation generates a unique physical ID and uses that ID for the repository name. For more information, see Name Type.",
4459
+ "required": false,
4460
+ "type": "Unknown",
4461
+ "update_causes": "replacement"
4462
+ },
4463
+ "RepositoryPolicyText": {
4464
+ "description": "A policy that controls who has access to the repository and which actions they can perform on it. For more information, see Amazon ECR Repository Policies in the Amazon EC2 Container Registry User Guide.",
4465
+ "required": false,
4466
+ "type": "Unknown",
4467
+ "update_causes": "none"
4468
+ }
4469
+ },
4470
+ "path": "aws-resource-ecr-repository.html"
4471
+ },
4157
4472
  "AWS::CloudTrail::Trail": {
4158
4473
  "properties": [
4159
4474
  "CloudWatchLogsLogGroupArn",
@@ -4174,7 +4489,7 @@
4174
4489
  "update_causes": "none"
4175
4490
  },
4176
4491
  "EnableLogFileValidation": {
4177
- "description": "Indicates whether CloudTrail validates the integrity of log files. When you disable log file integrity validation, CloudTrail stops creating digest files. For more information, see CreateTrail in the AWS CloudTrail API Reference.",
4492
+ "description": "Indicates whether CloudTrail validates the integrity of log files. By default, AWS CloudFormation sets this value to false. When you disable log file integrity validation, CloudTrail stops creating digest files. For more information, see CreateTrail in the AWS CloudTrail API Reference.",
4178
4493
  "required": false,
4179
4494
  "type": "Boolean",
4180
4495
  "update_causes": "none"
@@ -5212,7 +5527,7 @@
5212
5527
  "update_causes": "replacement"
5213
5528
  },
5214
5529
  "ShortName": {
5215
- "description": "The short name of the directory, such as CORP.",
5530
+ "description": "The NetBIOS name of the on-premises directory, such as CORP.",
5216
5531
  "required": false,
5217
5532
  "type": "String",
5218
5533
  "update_causes": "replacement"
@@ -5563,25 +5878,25 @@
5563
5878
  ],
5564
5879
  "full_properties": {
5565
5880
  "DestinationArn": {
5566
- "description": "The Amazon Resource Name (ARN) of the Amazon Kinesis stream that you want to use as the subscription feed destination.",
5881
+ "description": "The Amazon Resource Name (ARN) of the Amazon Kinesis stream or Lambda function that you want to use as the subscription feed destination.",
5567
5882
  "required": true,
5568
5883
  "type": "String",
5569
5884
  "update_causes": "replacement"
5570
5885
  },
5571
5886
  "FilterPattern": {
5572
- "description": "The filtering expressions that restrict what gets delivered to the destination Amazon Kinesis stream. For more information about the filter pattern syntax, see Filter and Pattern Syntax in the Amazon CloudWatch Developer Guide.",
5887
+ "description": "The filtering expressions that restrict what gets delivered to the destination AWS resource. For more information about the filter pattern syntax, see Filter and Pattern Syntax in the Amazon CloudWatch Developer Guide.",
5573
5888
  "required": true,
5574
5889
  "type": "String",
5575
5890
  "update_causes": "replacement"
5576
5891
  },
5577
5892
  "LogGroupName": {
5578
- "description": "The log group to associate with the subscription filter. All log events that are uploaded to this log group are filtered and delivered to the specified Amazon Kinesis stream if the filter pattern matches the log events.",
5893
+ "description": "The log group to associate with the subscription filter. All log events that are uploaded to this log group are filtered and delivered to the specified AWS resource if the filter pattern matches the log events.",
5579
5894
  "required": true,
5580
5895
  "type": "String",
5581
5896
  "update_causes": "replacement"
5582
5897
  },
5583
5898
  "RoleArn": {
5584
- "description": "An IAM role that grants CloudWatch Logs permission to put data into the specified Amazon Kinesis stream.",
5899
+ "description": "An IAM role that grants CloudWatch Logs permission to put data into the specified Amazon Kinesis stream. For Lambda and CloudWatch Logs destinations, don't specify this property because CloudWatch Logs gets the necessary permissions from the destination resource.",
5585
5900
  "required": false,
5586
5901
  "type": "String",
5587
5902
  "update_causes": "replacement"