convection 0.2.33 → 0.2.34.pre.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/CONTRIBUTING.md +22 -0
  4. data/README.md +15 -202
  5. data/Rakefile +3 -0
  6. data/docs/adding-new-resource-coverage.md +265 -0
  7. data/docs/canceling-stack-updates.md +5 -0
  8. data/docs/deleting-stacks.md +5 -0
  9. data/docs/getting-started.md +904 -0
  10. data/docs/index.md +69 -0
  11. data/docs/pygment.css +62 -0
  12. data/docs/relationship-to-cloudformation.md +51 -0
  13. data/docs/stacks.md +86 -0
  14. data/docs/template.html +130 -0
  15. data/example/getting-started-guide/Cloudfile +12 -0
  16. data/example/getting-started-guide/vpc.rb +74 -0
  17. data/example/stacks/Cloudfile +12 -0
  18. data/example/stacks/tasks/lookup_vpc_task.rb +28 -0
  19. data/example/stacks/templates/vpc.rb +14 -0
  20. data/lib/convection.rb +6 -0
  21. data/lib/convection/control/cloud.rb +1 -0
  22. data/lib/convection/control/stack.rb +126 -15
  23. data/lib/convection/model/cloudfile.rb +3 -0
  24. data/lib/convection/model/template/resource/aws_cloudfront_distribution.rb +24 -30
  25. data/lib/convection/model/template/resource/aws_ec2_dhcp_options.rb +38 -0
  26. data/lib/convection/model/template/resource/aws_ec2_security_group.rb +24 -2
  27. data/lib/convection/model/template/resource/aws_iam_user.rb +17 -3
  28. data/lib/convection/model/template/resource/aws_s3_bucket.rb +9 -3
  29. data/lib/convection/model/template/resource/aws_s3_bucket_policy.rb +10 -3
  30. data/lib/convection/model/template/resource/aws_sns_topic.rb +6 -3
  31. data/lib/convection/model/template/resource/aws_sns_topic_policy.rb +10 -3
  32. data/lib/convection/model/template/resource/aws_sqs_queue.rb +5 -3
  33. data/lib/convection/model/template/resource/aws_sqs_queue_policy.rb +10 -3
  34. data/spec/convection/model/template/resource/ec2_dhcp_options_spec.rb +55 -0
  35. data/yard_extensions.rb +4 -0
  36. data/yard_extensions/properties_handler.rb +30 -0
  37. data/yard_extensions/type_handler.rb +188 -0
  38. metadata +27 -23
  39. data/example/Cloudfile +0 -13
  40. data/example/deprecated/elb.rb +0 -27
  41. data/example/deprecated/iam_access_key.rb +0 -18
  42. data/example/deprecated/iam_group.rb +0 -31
  43. data/example/deprecated/iam_role.rb +0 -52
  44. data/example/deprecated/iam_user.rb +0 -31
  45. data/example/deprecated/rds.rb +0 -70
  46. data/example/deprecated/s3.rb +0 -13
  47. data/example/deprecated/sqs.rb +0 -32
  48. data/example/deprecated/vpc.rb +0 -85
  49. data/example/instances.rb +0 -93
  50. data/example/output/vpc.json +0 -335
  51. data/example/security-groups.rb +0 -77
  52. data/example/sqs-queue/Cloudfile +0 -19
  53. data/example/sqs-queue/README.md +0 -12
  54. data/example/trust_cloudtrail.rb +0 -24
  55. data/example/vpc.rb +0 -143
@@ -0,0 +1,38 @@
1
+ require_relative '../resource'
2
+
3
+ module Convection
4
+ module Model
5
+ class Template
6
+ class Resource
7
+ ##
8
+ # AWS::EC2::DHCPOptions
9
+ #
10
+ # @example
11
+ # ec2_dhcp_options 'TestOptions' do
12
+ # domain_name 'example.com'
13
+ # domain_name_servers '10.0.0.1', '10.0.0.2'
14
+ # netbios_name_servers '10.0.0.1', '10.0.0.2'
15
+ # netbios_node_type 1
16
+ # ntp_servers '10.0.0.1', '10.0.0.2'
17
+ # tag 'Name', 'Test'
18
+ # end
19
+ ##
20
+ class EC2DHCPOptions < Resource
21
+ include Model::Mixin::Taggable
22
+ type 'AWS::EC2::DHCPOptions'
23
+ property :domain_name, 'DomainName'
24
+ property :domain_name_servers, 'DomainNameServers', :type => :list
25
+ property :netbios_name_servers, 'NetbiosNameServers', :type => :list
26
+ property :netbios_node_type, 'NetbiosNodeType'
27
+ property :ntp_servers, 'NtpServers', :type => :list
28
+
29
+ def render(*args)
30
+ super.tap do |resource|
31
+ render_tags(resource)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -39,6 +39,12 @@ module Convection
39
39
  class Resource
40
40
  ##
41
41
  # AWS::EC2::SecurityGroup
42
+ #
43
+ # @example
44
+ # ec2_security_group 'SuperSecretSecurityGroup' do
45
+ # description 'This is a super secure group that nobody should know about.'
46
+ # vpc 'vpc-deadb33f'
47
+ # end
42
48
  ##
43
49
  class EC2SecurityGroup < Resource
44
50
  include DSL::Template::Resource::EC2SecurityGroup
@@ -47,9 +53,25 @@ module Convection
47
53
  attr_reader :security_group_ingress
48
54
  attr_reader :security_group_egress
49
55
 
50
- ##
51
- # Ingress/Egress Rule
56
+ # @example Egress rule
57
+ # ec2_security_group 'SuperSecretSecurityGroup' do
58
+ # # other properties...
52
59
  #
60
+ # egress_rule :tcp, 443 do
61
+ # # The source CIDR block.
62
+ # destination '10.10.10.0/24'
63
+ # end
64
+ # end
65
+ #
66
+ # @example Ingress rule
67
+ # ec2_security_group 'SuperSecretSecurityGroup' do
68
+ # # other properties...
69
+ #
70
+ # ingress_rule :tcp, 8080 do
71
+ # # The source security group ID.
72
+ # source_group stack.get('security-groups', 'HttpProxy')
73
+ # end
74
+ # end
53
75
  class Rule < Resource
54
76
  attribute :from
55
77
  attribute :to
@@ -35,9 +35,23 @@ module Convection
35
35
  module Model
36
36
  class Template
37
37
  class Resource
38
- ##
39
- # AWS::IAM::User
40
- ##
38
+ # @example
39
+ # iam_user 'User' do
40
+ # path "/my_path/region/example-cloud/"
41
+ # with_key
42
+ #
43
+ # policy 'bucket-policy' do
44
+ # allow do
45
+ # s3_resource 'bucket.blah.com', '*'
46
+ # s3_resource 'bucket.blah.com'
47
+ #
48
+ # action 's3:GetObject'
49
+ # action 's3:PutObject'
50
+ # action 's3:DeleteObject'
51
+ # action 's3:ListBucket'
52
+ # end
53
+ # end
54
+ # end
41
55
  class IAMUser < Resource
42
56
  include DSL::Template::Resource::IAMUser
43
57
 
@@ -4,9 +4,15 @@ module Convection
4
4
  module Model
5
5
  class Template
6
6
  class Resource
7
- ##
8
- # AWS::S3::Bucket
9
- ##
7
+ # @example
8
+ # s3_bucket 'BucketWithSNSNotification' do
9
+ # bucket_name "my-bucket.blah.com"
10
+ # notification_configuration(
11
+ # 'TopicConfigurations' => [
12
+ # {'Event' => 's3:ObjectCreated:*', 'Topic' => "arn:aws:sns:sns-topic-arn...."}
13
+ # ])
14
+ # with_output
15
+ # end
10
16
  class S3Bucket < Resource
11
17
  include Model::Mixin::Taggable
12
18
 
@@ -5,9 +5,16 @@ module Convection
5
5
  module Model
6
6
  class Template
7
7
  class Resource
8
- ##
9
- # AWS::S3::BucketPolicy
10
- ##
8
+ # @example
9
+ # s3_bucket_policy 'BucketPolicy' do
10
+ # bucket "my-bucket"
11
+ #
12
+ # allow do
13
+ # principal :AWS => '*'
14
+ # s3_resource "my-bucket", '*'
15
+ # action 's3:GetObject'
16
+ # end
17
+ # end
11
18
  class S3BucketPolicy < Resource
12
19
  extend Forwardable
13
20
 
@@ -4,9 +4,12 @@ module Convection
4
4
  module Model
5
5
  class Template
6
6
  class Resource
7
- ##
8
- # AWS::SNS::Topic
9
- ##
7
+ # @example
8
+ # sns_topic 'MyTopic' do
9
+ # display_name 'my topic'
10
+ # topic_name "example-topic"
11
+ # subscription [{"Protocol" => "sqs", "Endpoint" => "arn:aws:sqs:....}]
12
+ # end
10
13
  class SNSTopic < Resource
11
14
  type 'AWS::SNS::Topic'
12
15
  property :display_name, 'DisplayName'
@@ -5,9 +5,16 @@ module Convection
5
5
  module Model
6
6
  class Template
7
7
  class Resource
8
- ##
9
- # AWS::SNS::TopicPolicy
10
- ##
8
+ # @example
9
+ # sns_topic_policy 'TopicPolicy' do
10
+ # topic "my-sns-topic"
11
+ # allow do
12
+ # principal :Service => 's3.amazonaws.com'
13
+ # sns_resource my_region, my_account, "my-sns-topic"
14
+ # action 'sns:Publish'
15
+ # condition :ArnLike => { "AWS:SourceArn" => "arn:aws:s3:......." }
16
+ # end
17
+ # end
11
18
  class SNSTopicPolicy < Resource
12
19
  extend Forwardable
13
20
 
@@ -4,9 +4,11 @@ module Convection
4
4
  module Model
5
5
  class Template
6
6
  class Resource
7
- ##
8
- # AWS::SQS::Queue
9
- ##
7
+ # @example
8
+ # sqs_queue 'NotifyQueue' do
9
+ # queue_name "my-notify-queue"
10
+ # visibility_timeout 3600
11
+ # end
10
12
  class SQSQueue < Resource
11
13
  include Model::Mixin::Taggable
12
14
 
@@ -5,9 +5,16 @@ module Convection
5
5
  module Model
6
6
  class Template
7
7
  class Resource
8
- ##
9
- # AWS::SQS::QueuePolicy
10
- ##
8
+ # @example
9
+ # sqs_queue_policy 'QueuePolicy' do
10
+ # queue "my-queue"
11
+ # allow do
12
+ # principal '*'
13
+ # sqs_resource my_region, my_account, "my-queue"
14
+ # action 'sqs:SendMessage'
15
+ # condition :ArnEquals => { "AWS:SourceArn" => "arn:aws:sns:...." }
16
+ # end
17
+ # end
11
18
  class SQSQueuePolicy < Resource
12
19
  extend Forwardable
13
20
 
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ class Convection::Model::Template::Resource
4
+ describe EC2DHCPOptions do
5
+ let(:template) do
6
+ Convection.template do
7
+ ec2_dhcp_options 'TestOptions' do
8
+ domain_name 'example.com'
9
+ domain_name_servers '10.0.0.1', '10.0.0.2'
10
+ netbios_name_servers '10.0.0.1', '10.0.0.2'
11
+ netbios_node_type 1
12
+ ntp_servers '10.0.0.1', '10.0.0.2'
13
+ tag 'Name', 'Test'
14
+ end
15
+ end
16
+ end
17
+
18
+ subject do
19
+ template_json
20
+ .fetch('Resources')
21
+ .fetch('TestOptions')
22
+ .fetch('Properties')
23
+ end
24
+
25
+ it 'sets the DomainName' do
26
+ expect(subject['DomainName']).to eq('example.com')
27
+ end
28
+
29
+ it 'sets the DomainNameServers' do
30
+ expect(subject['DomainNameServers']).to match_array(['10.0.0.1', '10.0.0.2'])
31
+ end
32
+
33
+ it 'sets the NetbiosNameServers' do
34
+ expect(subject['NetbiosNameServers']).to match_array(['10.0.0.1', '10.0.0.2'])
35
+ end
36
+
37
+ it 'sets the NetbiosNodeType' do
38
+ expect(subject['NetbiosNodeType']).to eq(1)
39
+ end
40
+
41
+ it 'sets the NtpServers' do
42
+ expect(subject['NtpServers']).to match_array(['10.0.0.1', '10.0.0.2'])
43
+ end
44
+
45
+ it 'sets tags' do
46
+ expect(subject['Tags']).to include(hash_including('Key' => 'Name', 'Value' => 'Test'))
47
+ end
48
+
49
+ private
50
+
51
+ def template_json
52
+ JSON.parse(template.to_json)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,4 @@
1
+ # Load all Ruby files inside of the YARD extensions directory.
2
+ Dir.glob('yard_extensions/**.rb') do |file|
3
+ require_relative file
4
+ end
@@ -0,0 +1,30 @@
1
+ # A YARD handler to deal with the "property" DSL method.
2
+ class PropertyDslHandler < YARD::Handlers::Ruby::Base
3
+ handles method_call(:property)
4
+ namespace_only # Do not process nested method calls.
5
+
6
+ def process
7
+ name = statement.parameters.first.jump(:tstring_content, :ident).source
8
+ object = YARD::CodeObjects::MethodObject.new(namespace, name)
9
+ object.parameters = [['value', nil]]
10
+ register(object)
11
+
12
+ cf_property = statement.parameters[1].source
13
+ docstring = <<-DOC
14
+ @overload #{name}
15
+
16
+ Returns the value of the #{cf_property} CloudFormation property.
17
+ @overload #{name}(value)
18
+
19
+ Sets the #{cf_property} CloudFormation property.
20
+
21
+ @param value the value to set the #{cf_property} CloudFormation property to.
22
+ DOC
23
+ object.docstring = docstring if object.docstring.blank?(false)
24
+
25
+ # modify the object
26
+ object.dynamic = true
27
+ object.scope = :instance
28
+ object.name
29
+ end
30
+ end
@@ -0,0 +1,188 @@
1
+ # A YARD handler to deal with the "type" DSL method.
2
+ class TypeDslHandler < YARD::Handlers::Ruby::Base
3
+ handles method_call(:type)
4
+ namespace_only # Do not process nested method calls.
5
+
6
+ def process
7
+ name = call_params.first.dup
8
+
9
+ url = url_for_name(name)
10
+ cf_docs_tag = YARD::Docstring.new("@see #{url} #{name} CloudFormation documentation").tag('see')
11
+ namespace.docstring.add_tag(cf_docs_tag)
12
+ end
13
+
14
+ private
15
+
16
+ def url_for_name(name)
17
+ return URLS[name] if URLS.key?(name)
18
+
19
+ fail ArgumentError, "Resource name #{name.inspect} was not expected. " \
20
+ 'Please add it to TypeDslHandler::URLS to enable generation of a CloudFormation documentation link.'
21
+ end
22
+
23
+ URLS ||= {
24
+ 'AWS::ApiGateway::Account' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-account.html',
25
+ 'AWS::ApiGateway::ApiKey' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-apikey.html',
26
+ 'AWS::ApiGateway::Authorizer' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-authorizer.html',
27
+ 'AWS::ApiGateway::BasePathMapping' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-basepathmapping.html',
28
+ 'AWS::ApiGateway::ClientCertificate' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-clientcertificate.html',
29
+ 'AWS::ApiGateway::Deployment' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-deployment.html',
30
+ 'AWS::ApiGateway::Method' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-method.html',
31
+ 'AWS::ApiGateway::Model' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-model.html',
32
+ 'AWS::ApiGateway::Resource' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-resource.html',
33
+ 'AWS::ApiGateway::RestApi' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html',
34
+ 'AWS::ApiGateway::Stage' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-stage.html',
35
+ 'AWS::AutoScaling::AutoScalingGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-group.html',
36
+ 'AWS::AutoScaling::LaunchConfiguration' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-launchconfig.html',
37
+ 'AWS::AutoScaling::LifecycleHook' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html',
38
+ 'AWS::AutoScaling::ScalingPolicy' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-policy.html',
39
+ 'AWS::AutoScaling::ScheduledAction' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-scheduledaction.html',
40
+ 'AWS::CloudFormation::Authentication' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-authentication.html',
41
+ 'AWS::CloudFormation::CustomResource' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cfn-customresource.html',
42
+ 'AWS::CloudFormation::Init' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-init.html',
43
+ 'AWS::CloudFormation::Interface' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-interface.html',
44
+ 'AWS::CloudFormation::Stack' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-stack.html',
45
+ 'AWS::CloudFormation::WaitCondition' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-waitcondition.html',
46
+ 'AWS::CloudFormation::WaitConditionHandle' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-waitconditionhandle.html',
47
+ 'AWS::CloudFront::Distribution' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution.html',
48
+ 'AWS::CloudTrail::Trail' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudtrail-trail.html',
49
+ 'AWS::CloudWatch::Alarm' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cw-alarm.html',
50
+ 'AWS::CodeDeploy::Application' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codedeploy-application.html',
51
+ 'AWS::CodeDeploy::DeploymentConfig' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codedeploy-deploymentconfig.html',
52
+ 'AWS::CodeDeploy::DeploymentGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codedeploy-deploymentgroup.html',
53
+ 'AWS::CodePipeline::CustomActionType' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codepipeline-customactiontype.html',
54
+ 'AWS::CodePipeline::Pipeline' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codepipeline-pipeline.html',
55
+ 'AWS::Config::ConfigRule' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-config-configrule.html',
56
+ 'AWS::Config::ConfigurationRecorder' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-config-configurationrecorder.html',
57
+ 'AWS::Config::DeliveryChannel' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-config-deliverychannel.html',
58
+ 'AWS::DataPipeline::Pipeline' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datapipeline-pipeline.html',
59
+ 'AWS::DirectoryService::MicrosoftAD' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-directoryservice-microsoftad.html',
60
+ 'AWS::DirectoryService::SimpleAD' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-directoryservice-simplead.html',
61
+ 'AWS::DynamoDB::Table' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html',
62
+ 'AWS::EC2::CustomerGateway' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-customer-gateway.html',
63
+ 'AWS::EC2::DHCPOptions' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html',
64
+ 'AWS::EC2::EIP' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip.html',
65
+ 'AWS::EC2::EIPAssociation' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip-association.html',
66
+ 'AWS::EC2::FlowLog' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html',
67
+ 'AWS::EC2::Host' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-host.html',
68
+ 'AWS::EC2::Instance' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html',
69
+ 'AWS::EC2::InternetGateway' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-internet-gateway.html',
70
+ 'AWS::EC2::NatGateway' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-natgateway.html',
71
+ 'AWS::EC2::NetworkAcl' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html',
72
+ 'AWS::EC2::NetworkAclEntry' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html',
73
+ 'AWS::EC2::NetworkInterface' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html',
74
+ 'AWS::EC2::NetworkInterfaceAttachment' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface-attachment.html',
75
+ 'AWS::EC2::PlacementGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-placementgroup.html',
76
+ 'AWS::EC2::Route' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html',
77
+ 'AWS::EC2::RouteTable' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html',
78
+ 'AWS::EC2::SecurityGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html',
79
+ 'AWS::EC2::SecurityGroupEgress' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html',
80
+ 'AWS::EC2::SecurityGroupIngress' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html',
81
+ 'AWS::EC2::SpotFleet' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-spotfleet.html',
82
+ 'AWS::EC2::Subnet' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html',
83
+ 'AWS::EC2::SubnetNetworkAclAssociation' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-network-acl-assoc.html',
84
+ 'AWS::EC2::SubnetRouteTableAssociation' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-route-table-assoc.html',
85
+ 'AWS::EC2::Volume' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html',
86
+ 'AWS::EC2::VolumeAttachment' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volumeattachment.html',
87
+ 'AWS::EC2::VPC' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html',
88
+ 'AWS::EC2::VPCDHCPOptionsAssociation' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-dhcp-options-assoc.html',
89
+ 'AWS::EC2::VPCEndpoint' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html',
90
+ 'AWS::EC2::VPCGatewayAttachment' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-gateway-attachment.html',
91
+ 'AWS::EC2::VPCPeeringConnection' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcpeeringconnection.html',
92
+ 'AWS::EC2::VPNConnection' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html',
93
+ 'AWS::EC2::VPNConnectionRoute' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection-route.html',
94
+ 'AWS::EC2::VPNGateway' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-gateway.html',
95
+ 'AWS::EC2::VPNGatewayRoutePropagation' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-gatewayrouteprop.html',
96
+ 'AWS::ECR::Repository' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecr-repository.html',
97
+ 'AWS::ECS::Cluster' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-cluster.html',
98
+ 'AWS::ECS::Service' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-service.html',
99
+ 'AWS::ECS::TaskDefinition' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html',
100
+ 'AWS::EFS::FileSystem' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-efs-filesystem.html',
101
+ 'AWS::EFS::MountTarget' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-efs-mounttarget.html',
102
+ 'AWS::ElastiCache::CacheCluster' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-elasticache-cache-cluster.html',
103
+ 'AWS::ElastiCache::ParameterGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-elasticache-parameter-group.html',
104
+ 'AWS::ElastiCache::ReplicationGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-elasticache-replicationgroup.html',
105
+ 'AWS::ElastiCache::SecurityGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-elasticache-security-group.html',
106
+ 'AWS::ElastiCache::SecurityGroupIngress' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-elasticache-security-group-ingress.html',
107
+ 'AWS::ElastiCache::SubnetGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-elasticache-subnetgroup.html',
108
+ 'AWS::ElasticBeanstalk::Application' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-beanstalk.html',
109
+ 'AWS::ElasticBeanstalk::ApplicationVersion' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-beanstalk-version.html',
110
+ 'AWS::ElasticBeanstalk::ConfigurationTemplate' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-beanstalk-configurationtemplate.html',
111
+ 'AWS::ElasticBeanstalk::Environment' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-beanstalk-environment.html',
112
+ 'AWS::ElasticLoadBalancing::LoadBalancer' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-elb.html',
113
+ 'AWS::Elasticsearch::Domain' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-elasticsearch-domain.html',
114
+ 'AWS::EMR::Cluster' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-emr-cluster.html',
115
+ 'AWS::EMR::InstanceGroupConfig' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-emr-instancegroupconfig.html',
116
+ 'AWS::EMR::Step' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-emr-step.html',
117
+ 'AWS::Events::Rule' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-events-rule.html',
118
+ 'AWS::GameLift::Alias' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-gamelift-alias.html',
119
+ 'AWS::GameLift::Build' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-gamelift-build.html',
120
+ 'AWS::GameLift::Fleet' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-gamelift-fleet.html',
121
+ 'AWS::IAM::AccessKey' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-accesskey.html',
122
+ 'AWS::IAM::Group' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-group.html',
123
+ 'AWS::IAM::InstanceProfile' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-instanceprofile.html',
124
+ 'AWS::IAM::ManagedPolicy' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-managedpolicy.html',
125
+ 'AWS::IAM::Policy' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html',
126
+ 'AWS::IAM::Role' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html',
127
+ 'AWS::IAM::User' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-user.html',
128
+ 'AWS::IAM::UserToGroupAddition' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-addusertogroup.html',
129
+ 'AWS::IoT::Certificate' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-certificate.html',
130
+ 'AWS::IoT::Policy' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-policy.html',
131
+ 'AWS::IoT::PolicyPrincipalAttachment' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-policyprincipalattachment.html',
132
+ 'AWS::IoT::Thing' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-thing.html',
133
+ 'AWS::IoT::ThingPrincipalAttachment' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-thingprincipalattachment.html',
134
+ 'AWS::IoT::TopicRule' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-topicrule.html',
135
+ 'AWS::Kinesis::Stream' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-kinesis-stream.html',
136
+ 'AWS::KinesisFirehose::DeliveryStream' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-kinesisfirehose-deliverystream.html',
137
+ 'AWS::KMS::Key' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-kms-key.html',
138
+ 'AWS::Lambda::EventSourceMapping' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html',
139
+ 'AWS::Lambda::Alias' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-alias.html',
140
+ 'AWS::Lambda::Function' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html',
141
+ 'AWS::Lambda::Permission' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-permission.html',
142
+ 'AWS::Lambda::Version' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-version.html',
143
+ 'AWS::Logs::Destination' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-destination.html',
144
+ 'AWS::Logs::LogGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-loggroup.html',
145
+ 'AWS::Logs::LogStream' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-logstream.html',
146
+ 'AWS::Logs::MetricFilter' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-metricfilter.html',
147
+ 'AWS::Logs::SubscriptionFilter' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-subscriptionfilter.html',
148
+ 'AWS::OpsWorks::App' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-opsworks-app.html',
149
+ 'AWS::OpsWorks::ElasticLoadBalancerAttachment' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-opsworks-elbattachment.html',
150
+ 'AWS::OpsWorks::Instance' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-opsworks-instance.html',
151
+ 'AWS::OpsWorks::Layer' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-opsworks-layer.html',
152
+ 'AWS::OpsWorks::Stack' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-opsworks-stack.html',
153
+ 'AWS::RDS::DBCluster' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rds-dbcluster.html',
154
+ 'AWS::RDS::DBClusterParameterGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rds-dbclusterparametergroup.html',
155
+ 'AWS::RDS::DBInstance' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-database-instance.html',
156
+ 'AWS::RDS::DBParameterGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-dbparametergroup.html',
157
+ 'AWS::RDS::DBSecurityGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-security-group.html',
158
+ 'AWS::RDS::DBSecurityGroupIngress' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rds-security-group-ingress.html',
159
+ 'AWS::RDS::DBSubnetGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rds-dbsubnet-group.html',
160
+ 'AWS::RDS::EventSubscription' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rds-eventsubscription.html',
161
+ 'AWS::RDS::OptionGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rds-optiongroup.html',
162
+ 'AWS::Redshift::Cluster' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html',
163
+ 'AWS::Redshift::ClusterParameterGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clusterparametergroup.html',
164
+ 'AWS::Redshift::ClusterSecurityGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroup.html',
165
+ 'AWS::Redshift::ClusterSecurityGroupIngress' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersecuritygroupingress.html',
166
+ 'AWS::Redshift::ClusterSubnetGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-clustersubnetgroup.html',
167
+ 'AWS::Route53::HealthCheck' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53-healthcheck.html',
168
+ 'AWS::Route53::HostedZone' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53-hostedzone.html',
169
+ 'AWS::Route53::RecordSet' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-recordset.html',
170
+ 'AWS::Route53::RecordSetGroup' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-recordsetgroup.html',
171
+ 'AWS::S3::Bucket' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html',
172
+ 'AWS::S3::BucketPolicy' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-policy.html',
173
+ 'AWS::SDB::Domain' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-simpledb.html',
174
+ 'AWS::SNS::Topic' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sns-topic.html',
175
+ 'AWS::SNS::TopicPolicy' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sns-policy.html',
176
+ 'AWS::SQS::Queue' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-queues.html',
177
+ 'AWS::SQS::QueuePolicy' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-policy.html',
178
+ 'AWS::SSM::Document' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-document.html',
179
+ 'AWS::WAF::ByteMatchSet' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-waf-bytematchset.html',
180
+ 'AWS::WAF::IPSet' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-waf-ipset.html',
181
+ 'AWS::WAF::Rule' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-waf-rule.html',
182
+ 'AWS::WAF::SizeConstraintSet' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-waf-sizeconstraintset.html',
183
+ 'AWS::WAF::SqlInjectionMatchSet' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-waf-sqlinjectionmatchset.html',
184
+ 'AWS::WAF::WebACL' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-waf-webacl.html',
185
+ 'AWS::WAF::XssMatchSet' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-waf-xssmatchset.html',
186
+ 'AWS::WorkSpaces::Workspace' => 'http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-workspaces-workspace.html'
187
+ }.freeze
188
+ end