renderCFN 0.0.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/renderCFN/autoScalingGroup.rb +113 -0
- data/lib/renderCFN/awsObject.rb +31 -0
- data/lib/renderCFN/dnsWizard.rb +50 -0
- data/lib/renderCFN/instanceProfile.rb +25 -0
- data/lib/renderCFN/launchConfiguration.rb +95 -0
- data/lib/renderCFN/loadBalancer.rb +89 -0
- data/lib/renderCFN/mainStack.rb +70 -0
- data/lib/renderCFN/nestedStack.rb +51 -0
- data/lib/renderCFN/role.rb +45 -0
- data/lib/renderCFN/securityGroup.rb +31 -0
- data/lib/renderCFN/sqs.rb +29 -0
- data/lib/renderCFN/stack.rb +50 -0
- data/lib/renderCFN.rb +16 -0
- metadata +70 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 230fe739b45331751a429401c11ac60268064936
|
4
|
+
data.tar.gz: f0107df0063ff195eb3924a94b06369f88b4d9bd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ebdc39133784f47ad62a6e8a95fd4e75e741d64cfd47ec452b032f81c4dc6c09bd83df1af7e66571ac4025a059a8c75ac814c7d70728781ec8886b3a61729449
|
7
|
+
data.tar.gz: 158da39342803509f1520f73b2c4e6a80fe9ecae5efce0ee5c8d7e6b25888a0f65789246e0cbd48430c80c07edf8cc7b1a5c7d0fd60cb1b0979540ec3781dbb0
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'renderCFN/awsObject'
|
2
|
+
|
3
|
+
module RenderCFN
|
4
|
+
class AutoScalingGroup < AwsObject
|
5
|
+
def initialize( arguments)
|
6
|
+
@name = "#{arguments[:name]}AutoScalingGroup"
|
7
|
+
@awsObject = {
|
8
|
+
@name => {
|
9
|
+
'Type' => 'AWS::AutoScaling::AutoScalingGroup',
|
10
|
+
'Properties' => {
|
11
|
+
'TerminationPolicies' => [ 'OldestInstance' ],
|
12
|
+
'HealthCheckType' => arguments[:healthCheckEmergencyOverride] || arguments[:healthCheck],
|
13
|
+
'HealthCheckGracePeriod' => arguments[:healthCheckGracePeriod],
|
14
|
+
'LaunchConfigurationName' => { 'Ref' => "#{arguments[:name]}LaunchConfiguration" },
|
15
|
+
'VPCZoneIdentifier' => Array.new,
|
16
|
+
'MinSize' => arguments[:minSize],
|
17
|
+
'MaxSize' => arguments[:maxSize],
|
18
|
+
'Cooldown' => 300,
|
19
|
+
'Tags' => [
|
20
|
+
{ 'Key' => 'Name', 'Value' => "#{arguments[:serviceTitle]}", 'PropagateAtLaunch' => true },
|
21
|
+
{ 'Key' => 'stack', 'Value' => "#{@@environmentType}", 'PropagateAtLaunch' => true },
|
22
|
+
{ 'Key' => 'application', 'Value' => "#{arguments[:serviceTitle]}", 'PropagateAtLaunch' => true },
|
23
|
+
{ 'Key' => 'StackName', 'Value' => "#{@@stackName}", 'PropagateAtLaunch' => true },
|
24
|
+
{ 'Key' => 'PMData', 'Value' => "#{arguments[:pmData]}", 'PropagateAtLaunch' => true }
|
25
|
+
]
|
26
|
+
},
|
27
|
+
'DependsOn' => []
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
#I do not know why I have to do it this way... shrug
|
32
|
+
arguments[:subnetList].each do |subnet|
|
33
|
+
@awsObject[@name]['Properties']['VPCZoneIdentifier'].push( subnet)
|
34
|
+
end
|
35
|
+
|
36
|
+
unless arguments[:noelb] then
|
37
|
+
@awsObject[@name]['Properties']['LoadBalancerNames'] = Array.new
|
38
|
+
@awsObject[@name]['Properties']['LoadBalancerNames'].push( 'Ref' => "#{arguments[:name]}ElasticLoadBalancer" )
|
39
|
+
@awsObject[@name]['DependsOn'].push( "#{arguments[:name]}ElasticLoadBalancer")
|
40
|
+
end
|
41
|
+
|
42
|
+
@awsObject[@name]['DependsOn'].push( "#{arguments[:name]}LaunchConfiguration")
|
43
|
+
|
44
|
+
if arguments[:autoScalingRollingUpdateEnabled]
|
45
|
+
@awsObject[@name]['UpdatePolicy'] = {
|
46
|
+
'AutoScalingRollingUpdate' => {
|
47
|
+
'MinInstancesInService' => arguments[:minInstancesInService],
|
48
|
+
'MaxBatchSize' => arguments[:maxBatchSize],
|
49
|
+
'PauseTime' => "PT#{90 + arguments[:healthCheckGracePeriod]}S"
|
50
|
+
}
|
51
|
+
}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def addCpuScaling( args)
|
56
|
+
stuff = {
|
57
|
+
"#{@name}ScaleUP" => {
|
58
|
+
'Type' => 'AWS::AutoScaling::ScalingPolicy',
|
59
|
+
'Properties' => {
|
60
|
+
'AutoScalingGroupName' => {
|
61
|
+
'Ref' => @name,
|
62
|
+
},
|
63
|
+
'AdjustmentType' => 'ChangeInCapacity',
|
64
|
+
'ScalingAdjustment' => args[:changeUP]
|
65
|
+
}
|
66
|
+
},
|
67
|
+
"#{@name}ScaleDOWN" => {
|
68
|
+
'Type' => 'AWS::AutoScaling::ScalingPolicy',
|
69
|
+
'Properties' => {
|
70
|
+
'AutoScalingGroupName' => {
|
71
|
+
'Ref' => @name,
|
72
|
+
},
|
73
|
+
'AdjustmentType' => 'ChangeInCapacity',
|
74
|
+
'ScalingAdjustment' => args[:changeDOWN]
|
75
|
+
}
|
76
|
+
},
|
77
|
+
"#{@name}AlarmUP" => {
|
78
|
+
'Type' => 'AWS::CloudWatch::Alarm',
|
79
|
+
'Properties' => {
|
80
|
+
'ComparisonOperator' => 'GreaterThanOrEqualToThreshold',
|
81
|
+
'EvaluationPeriods' => 2,
|
82
|
+
'MetricName' => 'CPUUtilization',
|
83
|
+
'Namespace' => 'AWS/EC2',
|
84
|
+
'Period' => 60,
|
85
|
+
'Statistic' => 'Average',
|
86
|
+
'Threshold' => args[:cpuUP],
|
87
|
+
'AlarmActions' => [
|
88
|
+
'Ref' => "#{@name}ScaleUP"
|
89
|
+
]
|
90
|
+
}
|
91
|
+
},
|
92
|
+
"#{@name}AlarmDOWN" => {
|
93
|
+
'Type' => 'AWS::CloudWatch::Alarm',
|
94
|
+
'Properties' => {
|
95
|
+
'ComparisonOperator' => 'LessThanOrEqualToThreshold',
|
96
|
+
'EvaluationPeriods' => 40,
|
97
|
+
'MetricName' => 'CPUUtilization',
|
98
|
+
'Namespace' => 'AWS/EC2',
|
99
|
+
'Period' => 60,
|
100
|
+
'Statistic' => 'Average',
|
101
|
+
'Threshold' => args[:cpuDOWN],
|
102
|
+
'AlarmActions' => [
|
103
|
+
'Ref' => "#{@name}ScaleDOWN"
|
104
|
+
]
|
105
|
+
}
|
106
|
+
}
|
107
|
+
}
|
108
|
+
@awsObject.merge!( stuff)
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module RenderCFN
|
2
|
+
class AwsObject
|
3
|
+
|
4
|
+
def initialize( arguments)
|
5
|
+
@@action = arguments[:action] || nil
|
6
|
+
@@stackType = arguments[:stackType] || nil
|
7
|
+
@@environmentType = arguments[:environmentType] || nil
|
8
|
+
@@environmentName = arguments[:environmentName] || nil
|
9
|
+
@@stackName = "#{@@stackType}--#{@@environmentName}--#{@@environmentType}"
|
10
|
+
@@zoneID = arguments[:zoneID]
|
11
|
+
@@vpcID = arguments[:vpcID]
|
12
|
+
@@pmData = arguments[:pmData] || false
|
13
|
+
@@keyName = arguments[:keyName] || 'build'
|
14
|
+
@@ami = arguments[:ami]
|
15
|
+
@@bucket = arguments[:bucket]
|
16
|
+
@@subnetList = arguments[:subnetList]
|
17
|
+
@@publicSubnetList = arguments[:publicSubnetList]
|
18
|
+
@@healthCheckEmergencyOverride = arguments[:healthCheckEmergencyOverride]
|
19
|
+
end
|
20
|
+
|
21
|
+
def name
|
22
|
+
return @name
|
23
|
+
end
|
24
|
+
|
25
|
+
def get
|
26
|
+
return (@awsObject)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'renderCFN/awsObject'
|
2
|
+
|
3
|
+
module RenderCFN
|
4
|
+
class DnsWizard < AwsObject
|
5
|
+
def initialize( arguments )
|
6
|
+
@title = arguments[:name]
|
7
|
+
@name = "#{@title}DNS"
|
8
|
+
@awsObject = {
|
9
|
+
"#{@title}DNS" => {
|
10
|
+
'Type' => 'AWS::Route53::RecordSetGroup',
|
11
|
+
'Properties' => {
|
12
|
+
'HostedZoneId' => arguments[:zoneID],
|
13
|
+
'RecordSets' => [ ]
|
14
|
+
},
|
15
|
+
'DependsOn' => []
|
16
|
+
}
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def addARecord(name, ip, ttl = 300)
|
21
|
+
@awsObject[@name]['Properties']['RecordSets'].push( { 'Name' => name, 'ResourceRecords' => [ ip ], 'Type' => 'A', 'TTL'=> ttl } )
|
22
|
+
end
|
23
|
+
|
24
|
+
def addCNAMERecord( arguments)
|
25
|
+
|
26
|
+
unless arguments[:ttl]
|
27
|
+
ttl = 300
|
28
|
+
else
|
29
|
+
ttl = arguments[:ttl]
|
30
|
+
end
|
31
|
+
|
32
|
+
@awsObject[@name]['Properties']['RecordSets'].push( { 'Name' => arguments[:name], 'ResourceRecords' => [ arguments[:target] ], 'Type' => 'CNAME', 'TTL'=> ttl } )
|
33
|
+
end
|
34
|
+
|
35
|
+
def addLbDNS( arguments)
|
36
|
+
@awsObject[@name]['Properties']['RecordSets'].push(
|
37
|
+
{
|
38
|
+
'Name' => "#{arguments[:name]}.#{@@stackType}.#{@@environmentName}.#{@@environmentType}.aws.ecnext.net",
|
39
|
+
'Type' => 'A',
|
40
|
+
'AliasTarget'=> {
|
41
|
+
'HostedZoneId' => { "Fn::GetAtt" => [ "#{@title}ElasticLoadBalancer", "CanonicalHostedZoneNameID"] },
|
42
|
+
'DNSName' => { "Fn::GetAtt" => [ "#{@title}ElasticLoadBalancer", "DNSName"] }
|
43
|
+
}
|
44
|
+
}
|
45
|
+
)
|
46
|
+
@awsObject[@name]['DependsOn'].push( "#{@title}ElasticLoadBalancer")
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'renderCFN/awsObject'
|
2
|
+
|
3
|
+
module RenderCFN
|
4
|
+
class InstanceProfile < AwsObject
|
5
|
+
def initialize( name)
|
6
|
+
@name = "#{name}InstanceProfile"
|
7
|
+
@awsObject = {
|
8
|
+
@name => {
|
9
|
+
'Type' => 'AWS::IAM::InstanceProfile',
|
10
|
+
'Properties' => {
|
11
|
+
'Path' => '/',
|
12
|
+
'Roles' => Array.new
|
13
|
+
},
|
14
|
+
'DependsOn' => []
|
15
|
+
}
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def addRole( name)
|
20
|
+
@awsObject[@name]['Properties']['Roles'].push( 'Ref' => name)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'renderCFN/awsObject'
|
2
|
+
require 'base64'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
module RenderCFN
|
6
|
+
class LaunchConfiguration < AwsObject
|
7
|
+
def initialize( arguments)
|
8
|
+
@serviceName = arguments[:serviceName]
|
9
|
+
@serviceTitle = arguments[:serviceTitle]
|
10
|
+
@name = "#{arguments[:name]}LaunchConfiguration"
|
11
|
+
@startServices = arguments[:startServices]
|
12
|
+
@deployments = arguments[:deployments]
|
13
|
+
@pmData = arguments[:pmData]
|
14
|
+
@hostname = arguments[:hostname]
|
15
|
+
@cfnEBSVolume = arguments[:cfnEBSVolume]
|
16
|
+
@userDataOnBeforeStart = arguments[:userDataOnBeforeStart] || ''
|
17
|
+
@userDataOnAfterEnd = arguments[:userDataOnAfterEnd] || ''
|
18
|
+
@awsObject = {
|
19
|
+
@name => {
|
20
|
+
'Type' => 'AWS::AutoScaling::LaunchConfiguration',
|
21
|
+
'Properties' => {
|
22
|
+
'ImageId' => arguments[:ami],
|
23
|
+
'InstanceType' => arguments[:instanceType],
|
24
|
+
'KeyName' => arguments[:keyName],
|
25
|
+
'InstanceMonitoring' => false,
|
26
|
+
'BlockDeviceMappings' => [],
|
27
|
+
'SecurityGroups' => [
|
28
|
+
#{'Ref' => 'AdminSecurityGroup'},
|
29
|
+
#{'Ref' => 'AppServerSecurityGroup'}
|
30
|
+
]
|
31
|
+
},
|
32
|
+
'DependsOn' => []
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
if arguments[:publicIP]
|
37
|
+
@awsObject[@name]['Properties']['AssociatePublicIpAddress'] = true
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def addSecGroup( name)
|
43
|
+
@awsObject[@name]['Properties']['SecurityGroups'].push( name)
|
44
|
+
end
|
45
|
+
|
46
|
+
def addBlockDevice( deviceName, volumeSize, volumeType, iops = false, snapShotID = false)
|
47
|
+
ebs = Hash.new
|
48
|
+
ebs['DeleteOnTermination'] = true
|
49
|
+
ebs['Encrypted'] = false
|
50
|
+
ebs['VolumeSize'] = volumeSize
|
51
|
+
ebs['VolumeType'] = volumeType
|
52
|
+
|
53
|
+
if iops
|
54
|
+
ebs['Iops'] = iops
|
55
|
+
end
|
56
|
+
|
57
|
+
if snapShotID
|
58
|
+
ebs['SnapshotId'] = snapShotID
|
59
|
+
end
|
60
|
+
|
61
|
+
blockDevice = Hash.new
|
62
|
+
blockDevice['DeviceName'] = deviceName
|
63
|
+
blockDevice['Ebs'] = ebs
|
64
|
+
|
65
|
+
@awsObject[@name]['Properties']['BlockDeviceMappings'].push( blockDevice)
|
66
|
+
end
|
67
|
+
|
68
|
+
def addInstanceProfile( name)
|
69
|
+
@awsObject[@name]['Properties']['IamInstanceProfile'] = { 'Ref' => name }
|
70
|
+
@awsObject[@name]['DependsOn'].push( name)
|
71
|
+
end
|
72
|
+
|
73
|
+
def userData( file, common)
|
74
|
+
|
75
|
+
erbUserData = String.new
|
76
|
+
|
77
|
+
if File.exist?( "#{common}/UserData-start")
|
78
|
+
erbUserData = File.read( "#{common}/UserData-start")
|
79
|
+
end
|
80
|
+
|
81
|
+
if File.exist?( file)
|
82
|
+
erbUserData += File.read( file)
|
83
|
+
end
|
84
|
+
|
85
|
+
if File.exist?( "#{common}/UserData-end")
|
86
|
+
erbUserData += File.read( "#{common}/UserData-end")
|
87
|
+
end
|
88
|
+
|
89
|
+
userData = ERB.new( erbUserData)
|
90
|
+
@awsObject[@name]['Properties']['UserData'] = Base64.encode64(userData.result(binding))
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'renderCFN/awsObject'
|
2
|
+
|
3
|
+
module RenderCFN
|
4
|
+
class LoadBalancer < AwsObject
|
5
|
+
def initialize( arguments) #name, lbPort, instancePort, idleTimeout = 60)
|
6
|
+
@idleTimeout = arguments[:idleTimeout] or 60
|
7
|
+
@name = "#{arguments[:name]}ElasticLoadBalancer"
|
8
|
+
@awsObject = {
|
9
|
+
@name => {
|
10
|
+
'Type' => 'AWS::ElasticLoadBalancing::LoadBalancer',
|
11
|
+
'Properties' => {
|
12
|
+
'SecurityGroups' => [],
|
13
|
+
'Scheme' => arguments[:scheme] || 'internal',
|
14
|
+
'CrossZone' => true,
|
15
|
+
'ConnectionSettings' => {
|
16
|
+
'IdleTimeout' => @idleTimeout
|
17
|
+
},
|
18
|
+
'ConnectionDrainingPolicy' => { 'Enabled' => true, 'Timeout' => 60 },
|
19
|
+
'Subnets' => arguments[:subnetList],
|
20
|
+
'Tags' => [
|
21
|
+
{ 'Key' => 'application', 'Value' => arguments[:serviceTitle] },
|
22
|
+
{ 'Key' => 'StackName', 'Value' => @@stackName },
|
23
|
+
],
|
24
|
+
'HealthCheck' => {
|
25
|
+
'Target' => "HTTP:#{arguments[:instancePort]}/status-check",
|
26
|
+
'Interval' => 6,
|
27
|
+
'Timeout' => 5,
|
28
|
+
'UnhealthyThreshold' => 2,
|
29
|
+
'HealthyThreshold' => 2,
|
30
|
+
},
|
31
|
+
'Listeners' => [
|
32
|
+
{
|
33
|
+
'Protocol' => 'HTTP',
|
34
|
+
'LoadBalancerPort' => 80,
|
35
|
+
'InstancePort' => arguments[:instancePort]
|
36
|
+
},
|
37
|
+
#{
|
38
|
+
# 'Protocol' => 'HTTP',
|
39
|
+
# 'LoadBalancerPort' => 9876,
|
40
|
+
# 'InstancePort' => 9876
|
41
|
+
#}
|
42
|
+
]
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
if arguments[:lbPort] != 80
|
47
|
+
@awsObject['Properties']['Listeners'].push (
|
48
|
+
{
|
49
|
+
'Protocol' => 'HTTP',
|
50
|
+
'LoadBalancerPort' => arguments[:lbport],
|
51
|
+
'InstancePort' => arguments[:instancePort]
|
52
|
+
}
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
def modifyHealthCheck( newHealthCheck)
|
59
|
+
@awsObject[@name]['Properties']['HealthCheck']['Target'] = newHealthCheck
|
60
|
+
end
|
61
|
+
|
62
|
+
def addSecurityGroup( securityGroup)
|
63
|
+
@awsObject[@name]['Properties']['SecurityGroups'].push( {'Ref' => "#{securityGroup}"} )
|
64
|
+
end
|
65
|
+
|
66
|
+
def addListener( lbPort, instancePort)
|
67
|
+
@awsObject[@name]['Properties']['Listeners'].push (
|
68
|
+
{
|
69
|
+
'Protocol' => 'HTTP',
|
70
|
+
'LoadBalancerPort' => lbPort,
|
71
|
+
'InstancePort' => instancePort
|
72
|
+
}
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
def addSslListener( lbPort, instancePort, certificate)
|
77
|
+
@awsObject[@name]['Properties']['Listeners'].push (
|
78
|
+
{
|
79
|
+
'Protocol' => 'HTTPS',
|
80
|
+
'LoadBalancerPort' => lbPort,
|
81
|
+
'InstancePort' => instancePort,
|
82
|
+
'SSLCertificateId' => certificate
|
83
|
+
}
|
84
|
+
)
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'aws-sdk'
|
4
|
+
require 'renderCFN/stack'
|
5
|
+
|
6
|
+
module RenderCFN
|
7
|
+
class MainStack < Stack
|
8
|
+
def initialize( arguments)
|
9
|
+
|
10
|
+
super( arguments)
|
11
|
+
|
12
|
+
@stackID = String.new()
|
13
|
+
@templateName = 'main.yml'
|
14
|
+
@templateURL = "https://s3.amazonaws.com/#{@@bucket}/stacks/#{@@stackName}/#{@templateName}"
|
15
|
+
|
16
|
+
@awsObject = {
|
17
|
+
'AWSTemplateFormatVersion' => '2010-09-09',
|
18
|
+
'Description' => arguments[:description] ? "#{arguments[:description]} [renderCFN]" : 'Made with renderCFN',
|
19
|
+
'Resources' => {}
|
20
|
+
}
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def getAWSStackID( )
|
25
|
+
cfn = Aws::CloudFormation::Client.new( )
|
26
|
+
stackCall = cfn.describe_stacks(stack_name: @@stackName )
|
27
|
+
stackCall['stacks'][0]['stack_id']
|
28
|
+
end
|
29
|
+
|
30
|
+
def createStack()
|
31
|
+
uploadTemplate()
|
32
|
+
cfn = Aws::CloudFormation::Client.new( )
|
33
|
+
cfn.create_stack( stack_name: @@stackName, template_url: @templateURL, capabilities: ["CAPABILITY_IAM"])
|
34
|
+
@@stackID = getAWSStackID()
|
35
|
+
end
|
36
|
+
|
37
|
+
def updateStack()
|
38
|
+
uploadTemplate()
|
39
|
+
cfn = Aws::CloudFormation::Client.new( )
|
40
|
+
cfn.update_stack( stack_name: @@stackID, template_url: @templateURL, capabilities: ["CAPABILITY_IAM"] )
|
41
|
+
end
|
42
|
+
|
43
|
+
def deleteStack()
|
44
|
+
cfn = Aws::CloudFormation::Client.new( )
|
45
|
+
cfn.delete_stack( stack_name: @@stackName)
|
46
|
+
end
|
47
|
+
|
48
|
+
def validateStack()
|
49
|
+
cfn = Aws::CloudFormation::Client.new( )
|
50
|
+
cfn.validate_template( template_url: @templateURL)
|
51
|
+
end
|
52
|
+
|
53
|
+
def execute()
|
54
|
+
case @@action
|
55
|
+
when 'create'
|
56
|
+
createStack()
|
57
|
+
when 'delete'
|
58
|
+
deleteStack()
|
59
|
+
when 'update'
|
60
|
+
updateStack()
|
61
|
+
when 'validate'
|
62
|
+
validateStack()
|
63
|
+
when 'print'
|
64
|
+
render()
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
require 'renderCFN/stack'
|
3
|
+
|
4
|
+
module RenderCFN
|
5
|
+
class NestedStack < Stack
|
6
|
+
def initialize( arguments)
|
7
|
+
|
8
|
+
@serviceTitle = arguments[:serviceTitle] or nil
|
9
|
+
@serviceName = arguments[:serviceName] or nil
|
10
|
+
@nestedStackName = "#{@serviceName}NestedStack"
|
11
|
+
|
12
|
+
unless @serviceTitle and @serviceName then
|
13
|
+
print "Please set serviceTitle and serviceName\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
@stackID = String.new()
|
17
|
+
@templateName = "#{@serviceName}.yml"
|
18
|
+
@templateURL = "https://s3.amazonaws.com/#{@@bucket}/stacks/#{@@stackName}/#{@templateName}"
|
19
|
+
|
20
|
+
@awsObject = {
|
21
|
+
'AWSTemplateFormatVersion' => '2010-09-09',
|
22
|
+
'Description' => arguments[:description] ? "#{arguments[:description]} [renderCFN]" : 'Made with renderCFN',
|
23
|
+
'Resources' => {} ,
|
24
|
+
'Parameters' => {}
|
25
|
+
}
|
26
|
+
|
27
|
+
@nestedStackObject = {
|
28
|
+
@nestedStackName => {
|
29
|
+
'Type' => 'AWS::CloudFormation::Stack',
|
30
|
+
'Properties' => {
|
31
|
+
'TemplateURL' => @templateURL,
|
32
|
+
'Parameters' => {}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
def addParameter( dependentObject, type)
|
40
|
+
@awsObject['Parameters'].merge!( dependentObject => { 'Type' => type } )
|
41
|
+
@nestedStackObject[@nestedStackName]['Properties']['Parameters'].merge!( dependentObject => { 'Ref' => dependentObject } )
|
42
|
+
end
|
43
|
+
|
44
|
+
def getNestedStack()
|
45
|
+
uploadTemplate()
|
46
|
+
@nestedStackObject
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'renderCFN/awsObject'
|
2
|
+
|
3
|
+
module RenderCFN
|
4
|
+
class Role < AwsObject
|
5
|
+
def initialize( name)
|
6
|
+
@name = "#{name}Role"
|
7
|
+
@awsObject = {
|
8
|
+
@name => {
|
9
|
+
'Type' => 'AWS::IAM::Role',
|
10
|
+
'Properties' => {
|
11
|
+
'AssumeRolePolicyDocument' => {
|
12
|
+
'Statement' => [
|
13
|
+
'Effect' => 'Allow',
|
14
|
+
'Principal' => {
|
15
|
+
'Service' => [
|
16
|
+
'ec2.amazonaws.com'
|
17
|
+
]
|
18
|
+
},
|
19
|
+
'Action' => [
|
20
|
+
'sts:AssumeRole'
|
21
|
+
]
|
22
|
+
]
|
23
|
+
},
|
24
|
+
'Path' => '/',
|
25
|
+
'Policies' => []
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def addPolicy( name, action = Array.new, resource = Array.new)
|
32
|
+
@awsObject[@name]['Properties']['Policies'].push(
|
33
|
+
'PolicyName' => name,
|
34
|
+
'PolicyDocument' => {
|
35
|
+
'Statement' => [
|
36
|
+
'Effect' => 'Allow',
|
37
|
+
'Action' => action,
|
38
|
+
'Resource' => resource
|
39
|
+
]
|
40
|
+
}
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'renderCFN/awsObject'
|
2
|
+
|
3
|
+
module RenderCFN
|
4
|
+
class SecurityGroup < AwsObject
|
5
|
+
def initialize( arguments)
|
6
|
+
@name = "#{arguments[:name]}SecurityGroup"
|
7
|
+
@awsObject = {
|
8
|
+
@name => {
|
9
|
+
'Type' => 'AWS::EC2::SecurityGroup',
|
10
|
+
'Properties' => {
|
11
|
+
'GroupDescription' => arguments[:desc],
|
12
|
+
'VpcId' => arguments[:vpcID],
|
13
|
+
'SecurityGroupIngress' => [
|
14
|
+
]
|
15
|
+
}
|
16
|
+
}
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def addPort( protocol, ip, from, to)
|
21
|
+
entry = { 'IpProtocol' => protocol,
|
22
|
+
'CidrIp' => ip,
|
23
|
+
'FromPort' => from,
|
24
|
+
'ToPort' => to
|
25
|
+
}
|
26
|
+
@awsObject[@name]['Properties']['SecurityGroupIngress'].push( entry)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'renderCFN/awsObject'
|
2
|
+
|
3
|
+
module RenderCFN
|
4
|
+
class SQS < AwsObject
|
5
|
+
def initialize( arguments)
|
6
|
+
@name = "#{arguments[:name]}"
|
7
|
+
@awsObject = {
|
8
|
+
@name => {
|
9
|
+
'Type' => 'AWS::SQS::Queue',
|
10
|
+
'Properties' => {
|
11
|
+
'QueueName' => arguments[:name],
|
12
|
+
'DelaySeconds' => arguments[:delaySeconds],
|
13
|
+
'MaximumMessageSize' => arguments[:maximumMessageSize],
|
14
|
+
'MessageRetentionPeriod' => arguments[:messageRetentionPeriod],
|
15
|
+
'ReceiveMessageWaitTimeSeconds' => arguments[:receiveMessageWaitTimeSeconds],
|
16
|
+
'VisibilityTimeout' => arguments[:visibilityTimeout]
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def redrivePolicy( queueTarget, maxRecvCount)
|
23
|
+
@awsObject[@name]['Properties']['deadLetterTargetArn'] = queueTarget
|
24
|
+
@awsObject[@name]['Properties']['maxReceiveCount'] = maxRecvCount
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'aws-sdk'
|
5
|
+
require 'renderCFN/awsObject'
|
6
|
+
|
7
|
+
module RenderCFN
|
8
|
+
class Stack < AwsObject
|
9
|
+
|
10
|
+
def initialize( arguments)
|
11
|
+
|
12
|
+
super( arguments)
|
13
|
+
@stackID = String.new()
|
14
|
+
@templateName = 'main.yml'
|
15
|
+
@templateURL = "https://s3.amazonaws.com/#{@@bucket}/stacks/#{@@stackName}/#{@templateName}"
|
16
|
+
|
17
|
+
unless @@action then
|
18
|
+
print "Must set action.\n"
|
19
|
+
end
|
20
|
+
|
21
|
+
unless @@stackType and @@environmentType and @@environmentName then
|
22
|
+
print "Must set arguments for to stack name.\n"
|
23
|
+
exit 1
|
24
|
+
end
|
25
|
+
|
26
|
+
unless @@action == 'create' or @@action == 'print' then
|
27
|
+
@@stackID = getAWSStackID()
|
28
|
+
end
|
29
|
+
|
30
|
+
@awsObject = Hash.new
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
def render
|
35
|
+
YAML.dump(self.get)
|
36
|
+
end
|
37
|
+
|
38
|
+
def add( thing)
|
39
|
+
@awsObject['Resources'].merge!(thing)
|
40
|
+
end
|
41
|
+
|
42
|
+
def uploadTemplate( )
|
43
|
+
s3 = Aws::S3::Resource.new(region:'us-east-1')
|
44
|
+
obj = s3.bucket(@@bucket).object("stacks/#{@@stackName}/#{@templateName}")
|
45
|
+
obj.put(body: render)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
data/lib/renderCFN.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'renderCFN/autoScalingGroup.rb'
|
2
|
+
require 'renderCFN/awsObject.rb'
|
3
|
+
require 'renderCFN/dnsWizard.rb'
|
4
|
+
require 'renderCFN/instanceProfile.rb'
|
5
|
+
require 'renderCFN/launchConfiguration.rb'
|
6
|
+
require 'renderCFN/loadBalancer.rb'
|
7
|
+
require 'renderCFN/mainStack.rb'
|
8
|
+
require 'renderCFN/nestedStack.rb'
|
9
|
+
require 'renderCFN/role.rb'
|
10
|
+
require 'renderCFN/securityGroup.rb'
|
11
|
+
require 'renderCFN/stack.rb'
|
12
|
+
require 'renderCFN/sqs.rb'
|
13
|
+
|
14
|
+
module RenderCFN
|
15
|
+
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: renderCFN
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.17
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brian J. Schrock
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-10-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: Creates aws cloudformation templates
|
28
|
+
email: bschrock@manta.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- lib/renderCFN.rb
|
34
|
+
- lib/renderCFN/autoScalingGroup.rb
|
35
|
+
- lib/renderCFN/awsObject.rb
|
36
|
+
- lib/renderCFN/dnsWizard.rb
|
37
|
+
- lib/renderCFN/instanceProfile.rb
|
38
|
+
- lib/renderCFN/launchConfiguration.rb
|
39
|
+
- lib/renderCFN/loadBalancer.rb
|
40
|
+
- lib/renderCFN/mainStack.rb
|
41
|
+
- lib/renderCFN/nestedStack.rb
|
42
|
+
- lib/renderCFN/role.rb
|
43
|
+
- lib/renderCFN/securityGroup.rb
|
44
|
+
- lib/renderCFN/sqs.rb
|
45
|
+
- lib/renderCFN/stack.rb
|
46
|
+
homepage:
|
47
|
+
licenses:
|
48
|
+
- MIT
|
49
|
+
metadata: {}
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
requirements: []
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 2.6.13
|
67
|
+
signing_key:
|
68
|
+
specification_version: 4
|
69
|
+
summary: AWS Cloudformation template rendering tool
|
70
|
+
test_files: []
|