cfhighlander 0.2.0.alpha.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,172 @@
1
+ ec2-describe:
2
+ action:
3
+ - ec2:Describe*
4
+ - autoscaling:Describe*
5
+ - elasticloadbalancing:Describe*
6
+
7
+ ec2-cleanup-eni:
8
+ action:
9
+ - ec2:DeleteNetworkInterface
10
+ - ec2:DetachNetworkInterface
11
+
12
+ ec2-create-tag:
13
+ action:
14
+ - ec2:CreateTags
15
+
16
+ cloudwatch-logs:
17
+ action:
18
+ - logs:CreateLogGroup
19
+ - logs:CreateLogStream
20
+ - logs:PutLogEvents
21
+ - logs:DescribeLogStreams
22
+ - logs:DescribeLogGroups
23
+ resource:
24
+ - arn:aws:logs:*:*:*
25
+
26
+ cloudwatch-monitoring-writer:
27
+ action:
28
+ - cloudwatch:PutMetricData
29
+
30
+ cloudwatch-monitoring:
31
+ action:
32
+ - cloudwatch:PutMetricData
33
+ - cloudwatch:GetMetricStatistics
34
+ - cloudwatch:ListMetrics
35
+
36
+ s3-list-buckets:
37
+ action:
38
+ - s3:ListAllMyBuckets
39
+ - s3:ListBucket
40
+
41
+ s3-chef-ro:
42
+ action:
43
+ - s3:Get*
44
+ - s3:List*
45
+ resource:
46
+ - arn:aws:s3:::%{source_bucket}/chef
47
+ - arn:aws:s3:::%{source_bucket}/chef/*
48
+
49
+ s3-codedeploy-ro:
50
+ action:
51
+ - s3:Get*
52
+ - s3:List*
53
+ resource:
54
+ - arn:aws:s3:::%{source_bucket}/codedeploy
55
+ - arn:aws:s3:::%{source_bucket}/codedeploy/*
56
+
57
+ ecs-container-instance:
58
+ action:
59
+ - ecs:CreateCluster
60
+ - ecs:DeregisterContainerInstance
61
+ - ecs:DiscoverPollEndpoint
62
+ - ecs:Poll
63
+ - ecs:RegisterContainerInstance
64
+ - ecs:StartTelemetrySession
65
+ - ecs:Submit*
66
+ - ecr:GetAuthorizationToken
67
+ - ecr:BatchCheckLayerAvailability
68
+ - ecr:GetDownloadUrlForLayer
69
+ - ecr:BatchGetImage
70
+ - logs:CreateLogStream
71
+ - logs:PutLogEvents
72
+
73
+ ecs-service-role:
74
+ action:
75
+ - ecs:CreateCluster
76
+ - ecs:DeregisterContainerInstance
77
+ - ecs:DiscoverPollEndpoint
78
+ - ecs:Poll
79
+ - ecs:RegisterContainerInstance
80
+ - ecs:StartTelemetrySession
81
+ - ecs:Submit*
82
+ - ec2:AuthorizeSecurityGroupIngress
83
+ - ec2:Describe*
84
+ - elasticloadbalancing:DeregisterInstancesFromLoadBalancer
85
+ - elasticloadbalancing:Describe*
86
+ - elasticloadbalancing:RegisterInstancesWithLoadBalancer
87
+ - elasticloadbalancing:RegisterTargets
88
+ - elasticloadbalancing:DeregisterTargets
89
+ - autoscaling:Describe*
90
+
91
+ ecr-pull-images:
92
+ action:
93
+ - ecr:BatchCheckLayerAvailability
94
+ - ecr:BatchGetImage
95
+ - ecr:Get*
96
+ - ecr:List*
97
+
98
+ attach-ebs-volume:
99
+ action:
100
+ - ec2:DescribeVolumes
101
+ - ec2:AttachVolume
102
+ - ec2:DetachVolume
103
+
104
+ attach-network-interface:
105
+ action:
106
+ - ec2:DescribeNetworkInterfaces
107
+ - ec2:AttachNetworkInterface
108
+ - ec2:DetachNetworkInterface
109
+
110
+ associate-address:
111
+ action:
112
+ - ec2:AssociateAddress
113
+
114
+ ssm:
115
+ action:
116
+ - ssm:DescribeAssociation
117
+ - ssm:GetDeployablePatchSnapshotForInstance
118
+ - ssm:GetDocument
119
+ - ssm:GetParameters
120
+ - ssm:DescribeParameters
121
+ - ssm:ListAssociations
122
+ - ssm:ListInstanceAssociations
123
+ - ssm:PutInventory
124
+ - ssm:UpdateAssociationStatus
125
+ - ssm:UpdateInstanceAssociationStatus
126
+ - ssm:UpdateInstanceInformation
127
+
128
+ ec2messages:
129
+ action:
130
+ - ec2messages:AcknowledgeMessage
131
+ - ec2messages:DeleteMessage
132
+ - ec2messages:FailMessage
133
+ - ec2messages:GetEndpoint
134
+ - ec2messages:GetMessages
135
+ - ec2messages:SendReply
136
+
137
+ rds-backup-restore:
138
+ action:
139
+ - s3:ListBucket
140
+ - s3:GetBucketLocation
141
+ - s3:GetObjectMetaData
142
+ - s3:GetObject
143
+ - s3:PutObject
144
+ - s3:ListMultipartUploadParts
145
+ - s3:AbortMultipartUpload
146
+ resource:
147
+ - Fn::Join:
148
+ - ""
149
+ -
150
+ - 'arn:aws:s3:::'
151
+ - Fn::FindInMap:
152
+ - 'AccountId'
153
+ - Ref: 'AWS::AccountId'
154
+ - 'DatabaseBucket'
155
+ - Fn::Join:
156
+ - ""
157
+ -
158
+ - 'arn:aws:s3:::'
159
+ - Fn::FindInMap:
160
+ - 'AccountId'
161
+ - Ref: 'AWS::AccountId'
162
+ - 'DatabaseBucket'
163
+ - '/*'
164
+
165
+ spot-role:
166
+ action:
167
+ - ec2:DescribeImages
168
+ - ec2:DescribeSubnets
169
+ - ec2:RequestSpotInstances
170
+ - ec2:TerminateInstances
171
+ - ec2:DescribeInstanceStatus
172
+ - iam:PassRole
@@ -0,0 +1,55 @@
1
+ def service_role_assume_policy(service)
2
+ unless service.end_with? '.amazonaws.com'
3
+ service = "#{service}.amazonaws.com"
4
+ end
5
+ return {
6
+ Version: '2012-10-17',
7
+ Statement: [{ Effect: 'Allow', Principal: { Service: "#{service}" }, Action: 'sts:AssumeRole' }]
8
+ }
9
+ end
10
+
11
+
12
+ def iam_policy_allow(name, actions, resource='*')
13
+
14
+ return {
15
+ PolicyName: name,
16
+ PolicyDocument: {
17
+ Statement: [{
18
+ Sid: name.gsub('_', '').gsub('-', '').downcase,
19
+ Action: actions,
20
+ Resource: resource,
21
+ Effect: 'Allow'
22
+ }]
23
+ }
24
+ }
25
+ end
26
+
27
+ class IAMPolicies
28
+
29
+ def initialize(custom_policies = nil)
30
+ @managed_policies = YAML.load(File.read("#{File.dirname(__FILE__)}/config/managed_policies.yaml"))
31
+ @policy_array = Array.new
32
+ @policies = (not custom_policies.nil?) ? @managed_policies.merge(custom_policies) : @managed_policies
33
+ end
34
+
35
+ def get_policies(group = nil)
36
+ if group.kind_of?(Array)
37
+ puts group
38
+ create_policies(group)
39
+ else
40
+ create_policies(@config['default_policies']) if @config.key?('default_policies')
41
+ create_policies(@config['group_policies'][group]) unless group.nil?
42
+ end
43
+ return @policy_array
44
+ end
45
+
46
+ def create_policies(policies)
47
+ policies.each do |policy|
48
+ raise "ERROR: #{policy} policy doesn't exist in the managed policies or as a custom policy" if !@policies.key?(policy)
49
+ resource = (@policies[policy].key?('resource') ? (@policies[policy]['resource']) : ["*"])
50
+ @policy_array << { PolicyName: policy, PolicyDocument: { Statement: [{ Effect: 'Allow', Action: @policies[policy]['action'], Resource: resource }] } }
51
+ end
52
+ return @policy_array
53
+ end
54
+
55
+ end
@@ -0,0 +1,86 @@
1
+ require_relative './iam_helper'
2
+
3
+ def render_lambda_functions(cfndsl, lambdas, lambda_metadata, distribution)
4
+
5
+ custom_policies = (lambdas.key? 'custom_policies') ? lambdas['custom_policies'] : {}
6
+ lambdas['roles'].each do |lambda_role, role_config|
7
+ cfndsl.IAM_Role("LambdaRole#{lambda_role}") do
8
+ AssumeRolePolicyDocument service_role_assume_policy('lambda')
9
+ Path '/'
10
+ unless role_config['policies_inline'].nil?
11
+ Policies(
12
+ IAMPolicies.new(custom_policies).create_policies(role_config['policies_inline'])
13
+ )
14
+ end
15
+
16
+ unless role_config['policies_managed'].nil?
17
+ ManagedPolicyArns(role_config['policies_managed'])
18
+ end
19
+ end
20
+ end
21
+
22
+ lambdas['functions'].each do |key, lambda_config|
23
+ name = key
24
+ environment = lambda_config['environment'] || {}
25
+
26
+ # Create Lambda function
27
+ function_name = name
28
+ Lambda_Function(function_name) do
29
+ Code({
30
+ S3Bucket: distribution['bucket'],
31
+ S3Key: "#{distribution['prefix']}/#{distribution['version']}/#{lambda_metadata['path'][key]}"
32
+ })
33
+
34
+ Environment(Variables: Hash[environment.collect { |k, v| [k, v] }])
35
+
36
+ Handler(lambda_config['handler'] || 'index.handler')
37
+ MemorySize(lambda_config['memory'] || 128)
38
+ Role(FnGetAtt("LambdaRole#{lambda_config['role']}", 'Arn'))
39
+ Runtime(lambda_config['runtime'])
40
+ Timeout(lambda_config['timeout'] || 10)
41
+ if !lambda_config['vpc'].nil? && lambda_config['vpc']
42
+ # TODO implement VPC config
43
+ end
44
+
45
+ if !lambda_config['named'].nil? && lambda_config['named']
46
+ FunctionName(name)
47
+ end
48
+ end
49
+
50
+ Lambda_Version("#{name}Version#{lambda_metadata['version'][key]}") do
51
+ DeletionPolicy('Retain')
52
+ FunctionName(Ref(name))
53
+ CodeSha256(lambda_metadata['sha256'][key])
54
+ end
55
+
56
+ # Generate lambda function Policy
57
+ unless lambda_config['allowed_sources'].nil?
58
+ i = 1
59
+ lambda_config['allowed_sources'].each do |source|
60
+ Lambda_Permission("#{name}Permissions#{i}") do
61
+ FunctionName(Ref(name))
62
+ Action('lambda:InvokeFunction')
63
+ Principal(source['principal'])
64
+ end
65
+ i += 1
66
+ end
67
+ end
68
+
69
+ # Scheduled triggering of lambda function
70
+ if lambda_config.key?('schedules')
71
+ lambda_config['schedules'].each_with_index do |schedule, index|
72
+ Events_Rule("Lambda#{name}Schedule#{index}") do
73
+ ScheduleExpression("cron(#{schedule['cronExpression']})")
74
+ State('ENABLED')
75
+ target = {
76
+ 'Arn' => FnGetAtt(name, 'Arn'), 'Id' => "lambda#{name}",
77
+ }
78
+ target['Input'] = schedule['payload'] if schedule.key?('payload')
79
+ Targets([target])
80
+ end
81
+ end
82
+ end
83
+
84
+
85
+ end
86
+ end
data/cfndsl_ext/sg.rb ADDED
@@ -0,0 +1,26 @@
1
+
2
+ def sg_create_rules (x, ip_blocks={})
3
+ rules = []
4
+ x.each do | group |
5
+ group['ips'].each do |ip|
6
+ group['rules'].each do |rule|
7
+ lookup_ips_for_sg(ip_blocks, ip).each do |cidr|
8
+ rules << { IpProtocol: "#{rule['IpProtocol']}", FromPort: "#{rule['FromPort']}", ToPort: "#{rule['ToPort']}", CidrIp: cidr }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ return rules
14
+ end
15
+
16
+
17
+ def lookup_ips_for_sg (ips, ip_block_name={})
18
+ if ip_block_name == 'stack'
19
+ cidr = [FnJoin( "", [ "10.", Ref('StackOctet'), ".", "0.0/16" ] )]
20
+ elsif ips.has_key? ip_block_name
21
+ cidr = ips[ip_block_name]
22
+ else
23
+ cidr = [ip_block_name]
24
+ end
25
+ cidr
26
+ end
@@ -0,0 +1,13 @@
1
+ require 'aws-sdk-s3'
2
+
3
+ def aws_credentials
4
+ # TODO implement credentials e.g. for environment create/update/delete
5
+ end
6
+
7
+ def s3_bucket_region(bucket)
8
+ s3 = Aws::S3::Client.new
9
+ location = s3.get_bucket_location({ bucket: bucket }).location_constraint
10
+ location = 'us-east-1' if location == ''
11
+ location = 'eu-west-1' if location == 'EU'
12
+ location
13
+ end
@@ -0,0 +1,21 @@
1
+ class ::Hash
2
+ def deep_merge(second)
3
+ merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
4
+ self.merge(second.to_h, &merger)
5
+ end
6
+
7
+
8
+ def extend(second)
9
+ second.each { |k, v|
10
+
11
+ if ((self.key? k) and (v.is_a? Hash and self[k].is_a? Hash))
12
+ self[k].extend(v)
13
+ else
14
+ self[k] = v
15
+ end
16
+
17
+ } if second.is_a? Hash
18
+
19
+ self
20
+ end
21
+ end
@@ -0,0 +1,99 @@
1
+ require_relative '../lib/highlander.mapproviders'
2
+
3
+ # Return mapping provider as class
4
+ def mappings_provider(provider_name)
5
+ return nil if provider_name.nil?
6
+ provider = nil
7
+ providers = Object.const_get('Highlander').const_get('MapProviders')
8
+ begin
9
+ providers.const_get(provider_name)
10
+ rescue NameError => e
11
+ if e.to_s.include? 'uninitialized constant Highlander::MapProviders::'
12
+ return nil
13
+ end
14
+ STDERR.puts(e.to_s)
15
+ raise e
16
+ end
17
+ end
18
+
19
+ # Return all of the maps from mapping provider
20
+ def mappings_provider_maps(provider_name, config)
21
+ provider = mappings_provider(provider_name)
22
+
23
+ if provider.nil?
24
+ STDERR.puts("Can't find mapping provider #{provider_name} and it's maps")
25
+ return nil
26
+ else
27
+ return provider.getMaps(config)
28
+ end
29
+ end
30
+
31
+ # Renders CloudFormation function for retrieving Mapping value. If key name and map name are not given,
32
+ # extraction from mapping provider will be tried
33
+ def mapping_value(component:, provider_name:, value_name:, key_name: nil)
34
+
35
+ provider = nil
36
+
37
+ # if key name is nil, provider must provide key
38
+ if key_name.nil?
39
+ provider = mappings_provider(provider_name)
40
+ if provider.nil?
41
+ STDERR.puts("Error: mapping provider #{provider_name} not found, can't render value of #{value_name} attribute")
42
+ return nil
43
+ end
44
+ unless provider.respond_to? 'getDefaultKey'
45
+ STDERR.puts("Error: #{provider} does not implement getDefaultKey. Can't render value of #{value_name} attribtue")
46
+ return nil
47
+ end
48
+
49
+ key_name = provider.getDefaultKey
50
+ end
51
+
52
+ # Map name defaults to provider name. If provider exists and implements getMapName
53
+ # map name will be dynamically resolved via this method
54
+ map_name = provider_name
55
+
56
+ provider = mappings_provider(provider_name) if provider.nil?
57
+ unless provider.nil?
58
+ if provider.respond_to? 'getMapName'
59
+ map_name = provider.getMapName
60
+ end
61
+ end
62
+
63
+ # there is no provider
64
+ # and map name is not a reference
65
+ if((provider.nil?) and (not map_name.start_with? 'Ref('))
66
+ # check if mapping exists on component
67
+ unless ((component.config['mappings'].key? map_name))
68
+ STDERR.puts("Could not resolve mapping value: MapName=#{map_name},Key=#{key_name},Attribute=#{value_name}")
69
+ return nil
70
+ end
71
+ end
72
+
73
+ # both map name and key name could be predefined via intrinsic functions
74
+ if map_name.class == Hash
75
+ map_name = map_name.to_s
76
+ elsif( not map_name.include? 'Ref(')
77
+ map_name = "'#{map_name}'"
78
+ end
79
+
80
+ if key_name.class == Hash
81
+ key_name = key_name.to_s
82
+ elsif( not key_name.include? 'Ref(')
83
+ key_name = "'#{key_name}'"
84
+ end
85
+
86
+ if value_name.nil?
87
+ STDERR.puts("No value defined for mapping parameter. MapName=#{map_name},Key=#{key_name},Attribute=#{value_name}")
88
+ return nil
89
+ end
90
+ if value_name.class == Hash
91
+ value_name = value_name.to_s
92
+ elsif( not value_name.include? 'Ref(')
93
+ value_name = "'#{value_name}'"
94
+ end
95
+
96
+
97
+ return "FnFindInMap(#{map_name},#{key_name},#{value_name})"
98
+
99
+ end
data/hl_ext/vpc.rb ADDED
@@ -0,0 +1,12 @@
1
+ def subnet_parameters(subnets, maximum_availability_zones)
2
+ subnets.each { |subnet_name, subnet_config|
3
+ # Account mappings for AZs
4
+ maximum_availability_zones.times do |x|
5
+
6
+ # Request output from other component as input
7
+ # to this component
8
+ OutputParam component: 'vpc', name: "Subnet#{subnet_config['name']}#{x}"
9
+
10
+ end
11
+ }
12
+ end