aws-must 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +235 -0
  3. data/bin/aws-must.rb +92 -0
  4. data/demo/0/conf.yaml +1 -0
  5. data/demo/0/root.mustache +1 -0
  6. data/demo/1/conf.yaml +1 -0
  7. data/demo/1/root.mustache +22 -0
  8. data/demo/2/conf.yaml +6 -0
  9. data/demo/2/root.mustache +54 -0
  10. data/demo/3/conf.yaml +3 -0
  11. data/demo/3/resources.mustache +26 -0
  12. data/demo/3/root.mustache +85 -0
  13. data/demo/4/conf.yaml +22 -0
  14. data/demo/4/resource.mustache +27 -0
  15. data/demo/4/resourceInstance.mustache +32 -0
  16. data/demo/4/resources.mustache +25 -0
  17. data/demo/4/root.mustache +95 -0
  18. data/demo/5/conf.yaml +32 -0
  19. data/demo/5/output.mustache +39 -0
  20. data/demo/5/resource.mustache +26 -0
  21. data/demo/5/resourceInstance.mustache +35 -0
  22. data/demo/5/resources.mustache +25 -0
  23. data/demo/5/root.mustache +100 -0
  24. data/demo/6/conf.yaml +31 -0
  25. data/demo/6/mappings.mustache +67 -0
  26. data/demo/6/output.mustache +40 -0
  27. data/demo/6/resource.mustache +29 -0
  28. data/demo/6/resourceInstance.mustache +35 -0
  29. data/demo/6/resources.mustache +35 -0
  30. data/demo/6/root.mustache +133 -0
  31. data/demo/7/conf.yaml +54 -0
  32. data/demo/7/mappings.mustache +67 -0
  33. data/demo/7/output.mustache +40 -0
  34. data/demo/7/parameter.mustache +38 -0
  35. data/demo/7/resource.mustache +38 -0
  36. data/demo/7/resourceInstance.mustache +45 -0
  37. data/demo/7/resourceSecurityGroup.mustache +37 -0
  38. data/demo/7/resources.mustache +35 -0
  39. data/demo/7/root.mustache +157 -0
  40. data/demo/7/tag.mustache +30 -0
  41. data/lib/aws-must/aws-must.rb +96 -0
  42. data/lib/aws-must/docu.rb +164 -0
  43. data/lib/aws-must/template.rb +81 -0
  44. data/lib/aws-must.rb +11 -0
  45. data/lib/tasks/demo.rake +139 -0
  46. data/lib/utils/hasher.rb +83 -0
  47. data/lib/utils/logger.rb +71 -0
  48. metadata +106 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ec263031a8d6a6619934045ec286e400ddf00a72
4
+ data.tar.gz: f1b69d4f681dc1551986be9f505540dd17337f1b
5
+ SHA512:
6
+ metadata.gz: ce14b0078feac91d303e3b313ce9f33eab39afb966bdf11ee52efdee6f6e9e4380ce330b7daa8ea203b7651d580e41d3d7409c1494cf09139ed4be390a1c1bed
7
+ data.tar.gz: 47a828370761ca394473cea460a2b337d2f9c2a3990ca96ae701317dde6ebf467b523a4408a4632b2b60859b683470567259d428fcd8366c475feb98e1d539b8
data/README.md ADDED
@@ -0,0 +1,235 @@
1
+ # aws-must - Minimum Viable Solution to Manage CloudFormation Templates - $Release:0.0.2$
2
+
3
+ `aws-must` is a tool, which allows separating infrastructure
4
+ configuration and Amazon related syntax using
5
+ [YAML](http://learnxinyminutes.com/docs/yaml) and
6
+ [Mustache templates](https://mustache.github.io/).
7
+
8
+
9
+ ## The Problem
10
+
11
+ [Amazon CloudFormation](http://aws.amazon.com/cloudformation/) gives
12
+ developers and systems administrators an easy way to create and manage
13
+ a collection of related AWS resources. It uses JSON -formatted
14
+ [templates](http://aws.amazon.com/cloudformation/aws-cloudformation-templates)
15
+ for defining services to be managed together as a "stack".
16
+
17
+ However, the CF -templates soon become quite convoluted as the
18
+ complexity of the infrastructure stack increases. In addition, the
19
+ JSON format adds more to the management difficulties:
20
+
21
+ 1. each stack is represented as a monolithic JSON document.
22
+
23
+ 2. templates mix infrastructure specific configuration with the syntax
24
+ stipulated by
25
+ [Amazon CloudFormation Template Reference](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-reference.html)
26
+
27
+ 3. the JSON format doesn't support expressing references, and
28
+ CloudFormation needs to use a
29
+ [special syntax](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html)
30
+ to define relations across template elements.
31
+
32
+ 4. the JSON format doesn't support comments, which could be used to
33
+ add documentation into the templates.
34
+
35
+ 5. JSON documents repeat similar sections as resource instances are
36
+ defined individually as sub-documents.
37
+
38
+ 6. JSON adds it own markup overhead to the configuration.
39
+
40
+ ## The solution
41
+
42
+ `aws-tool` helps mitigating the problems presented in the chapter
43
+ above. With the tool users may
44
+
45
+ 1. split stack configuration first in half, using YAML/mustache
46
+ templates, and then further down using Mustache partials
47
+
48
+ 2. separate infrastructure specific configuration from syntax
49
+ stipulated by
50
+ [Amazon CloudFormation Template Reference](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-reference.html)
51
+ using YAML and Mustache templates.
52
+
53
+ 3. use YAML anchors to express dependencies between infrastructure
54
+ elements.
55
+
56
+ 4. add comments in YAML and Mustache templates. The tool supports
57
+ simple tag syntax (**++start++**
58
+ **++close++** -tags) to add documentation to
59
+ Mustache templates, which can be extracted to a separate document.
60
+
61
+ 5. use Mustache partials to get rid of repeating similar sections in
62
+ JSON configuration.
63
+
64
+ 6. concentrate on configurations expressed in YAML (with minimal markdown).
65
+
66
+
67
+ ## Installation
68
+
69
+ Add following line to `Gemfile`
70
+
71
+ gem 'aws-must'
72
+
73
+
74
+ and run
75
+
76
+ bundle install
77
+
78
+
79
+ ## Usage
80
+
81
+ ### CLI Usage
82
+
83
+ To get help
84
+
85
+ aws-must.rb help
86
+
87
+ To create CloudFormation JSON template for `yaml_file` using default
88
+ template `./mustache/root.mustache` issue the command
89
+
90
+ aws-must.rb gen yaml_file
91
+
92
+ To extract documentation between **++start++**
93
+ **++close++** -tags from template
94
+ `./mustache/root.mustache` issue the command
95
+
96
+ aws-must.rb doc
97
+
98
+ To dump YAML `yaml_file` in JSON format
99
+
100
+ aws-must.rb json yaml_file
101
+
102
+
103
+ ### Demo Usage
104
+
105
+ Add the following lines to `Rakefile`
106
+
107
+
108
+ spec = Gem::Specification.find_by_name 'aws-must'
109
+ load "#{spec.gem_dir}/lib/tasks/demo.rake"
110
+
111
+
112
+ and verify that `demo` namespace is added to rake tasks
113
+
114
+ rake -T demo
115
+
116
+ #### Demo Usage Locally
117
+
118
+ A list of demo cases is shown with the command
119
+
120
+ rake -T demo:template
121
+
122
+ To show the CloudFormation JSON rendered for a demo case `i`, where
123
+ `i` ranges from `1,2,3, ...`, run rake task `dev:template-i`. For
124
+ example, for demo case `1` run
125
+
126
+ rake demo:template-1
127
+
128
+ To show the difference of running case `i` vs. running the previous
129
+ demo case, run rake task `demo:diff-i`. For example, for demo case `2`
130
+ run
131
+
132
+ rake demo:diff-2
133
+
134
+ **NOTICE:**: The [jq](http://stedolan.github.io/jq/) must be installed
135
+ for diff target to work.
136
+
137
+ To show html documentation extracted from demo case `i` templates, run
138
+ rake task `demo:html-i`. For example, for demo case `3` run
139
+
140
+ rake demo:html-3
141
+
142
+ **NOTICE:**: Uses `markdown` command to convert
143
+ [markdown](http://daringfireball.net/projects/markdown) documentation
144
+ into html.
145
+
146
+ **NOTICE:**: Default browser `firefox` can be changed using command
147
+ line argument `browser`, e.g. `rake demo:html-3[chromium-browser]`.
148
+
149
+ #### Use Demo to Bootstrap Own Configuration
150
+
151
+ To extract your own copy of demo case `i` configuration, run rake task
152
+ `demo:bootstrap-i` with command line arguments defining template
153
+ directory and configuration directory. For example, to copy demo case
154
+ `3` templates to directory `tmp/tmpl` and configurations to
155
+ `tmp/conf`, run
156
+
157
+ rake demo:bootstrap-3[tmp/tmpl,tmp/conf]
158
+
159
+
160
+ After this command `tmp/tmpl` contains `root.mustache`, which is the
161
+ starting point of mustache template rendering, and `tmp/conf` contains
162
+ a YAML file `conf.yaml` for demo configuration data.
163
+
164
+
165
+ #### Demo Usage on Amazon platform
166
+
167
+ Demo stacks can be provisioned on Amazon platform.
168
+
169
+ **WARNING** Provisioning CloudFormation templates on Amazon will be
170
+ **charged according to Amazon pricing policies**.
171
+
172
+ Prerequisites:
173
+
174
+ * [Install Amazon AWS Command Line Interface](http://docs.aws.amazon.com/cli/latest/userguide/installing.html)
175
+ * [Configure AWS Command Line Interface](http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html)
176
+
177
+ To demo targets, which provision Amazon, run
178
+
179
+ rake -T demo:stack-create
180
+
181
+ **NOTICE**: Please, notice the region constraint in the output. Some
182
+ of the templates use fixed AMI configuration, which means that they
183
+ work only if aws -tool defines correct region (typically in set in
184
+ `~/.aws/config` file).
185
+
186
+ **NOTICE**: Demo-case `7,8, ...` make use of public ssh-key
187
+ `demo-key`. See
188
+ [Amazon EC2 Key Pairs](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html),
189
+ which explains how to upload your own key to Amazon platform.
190
+
191
+ To create a `demo` stack for demo case `i`, for example demo case 7
192
+ run
193
+
194
+ rake demo:stack-create-7
195
+
196
+ To show events generated when `demo` stack is created run
197
+
198
+ rake demo:stack-events
199
+
200
+ To show status of `demo` stack run
201
+
202
+ rake demo:stack-status
203
+
204
+ Instances created in demo cases `7,8,...` can be connected using ssh.
205
+ Demo target `demo:stack-ssh` locates an ip address from stack output
206
+ variable, and launches ssh command with the ip and the identity given
207
+ as a parameter.
208
+
209
+ For example to use ip address in demo stack output variable `IP1`, and
210
+ with the identity `~/.ssh/demo-key/demo-key`, run
211
+
212
+ rake demo:stack-ssh[IP1,~/.ssh/demo-key/demo-key]
213
+
214
+ where
215
+
216
+ * `IP1` : is the name of stack output variable holding IP address
217
+ (cf. Outputs array in `rake demo:stack-status`)
218
+ * `~/.ssh/demo-key/demo-key` is the file path of ssh private key for
219
+ [Amazon SSH-key pair](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)
220
+ `demo-key`.
221
+
222
+
223
+ To delete `demo` stack
224
+
225
+ rake demo:stack-delete
226
+
227
+
228
+
229
+
230
+
231
+
232
+
233
+
234
+
235
+
data/bin/aws-must.rb ADDED
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ require 'thor'
5
+ require_relative '../lib/aws-must'
6
+
7
+ class App < Thor
8
+
9
+ include Utils::MyLogger # mix logger
10
+ PROGNAME = "main" # logger progname
11
+ DEAFAULT_TEMPLATE="root" # name of template in :template_path -directory
12
+
13
+
14
+ # ------------------------------------------------------------------
15
+
16
+ class_option :log, :aliases => "-l", :type =>:string, :default => nil,
17
+ :enum => [ "DEBUG", "INFO", "WARN", "ERROR" ],
18
+ :desc => "Set debug level "
19
+
20
+ # ------------------------------------------------------------------
21
+ # action 'doc'
22
+
23
+ desc "doc", "Extract template documentation"
24
+
25
+ option :template_path, :aliases => "-t", :type => :string,
26
+ :default => "mustache",
27
+ :desc => "Directory holding mustache templates"
28
+
29
+ long_desc <<-LONGDESC
30
+
31
+ Extract documation from <template_name> in ':template_path' -direcotory.
32
+
33
+ <template_name> defaults to '#{DEAFAULT_TEMPLATE}'
34
+
35
+ LONGDESC
36
+
37
+ def doc( template_name=DEAFAULT_TEMPLATE )
38
+
39
+ app = ::AwsMust::AwsMust.new( options )
40
+ app.doc( template_name )
41
+
42
+ end
43
+
44
+ # ------------------------------------------------------------------
45
+ # action 'json'
46
+
47
+ desc "json <yaml_file>", "Dump configuration in JSON format"
48
+
49
+ long_desc <<-LONGDESC
50
+
51
+ Reads <yaml_file> and dumps it to stdout in JSON format.
52
+
53
+ LONGDESC
54
+
55
+
56
+ def json( yaml_file )
57
+
58
+ app = ::AwsMust::AwsMust.new( options )
59
+ app.json( yaml_file )
60
+
61
+ end
62
+
63
+
64
+ # ------------------------------------------------------------------
65
+ # action 'gen'
66
+
67
+ desc "gen <yaml_file> [<template_name>]", "Generate CloudFormation JSON template"
68
+
69
+ option :template_path, :aliases => "-t", :type => :string,
70
+ :default => "mustache",
71
+ :desc => "Directory holding mustache templates"
72
+
73
+ long_desc <<-LONGDESC
74
+
75
+ Generate Amazon CloudFormation JSON file for <yaml_file> using
76
+ <template_name> in ':template_path' -direcotory.
77
+
78
+ <template_name> defaults to '#{DEAFAULT_TEMPLATE}'
79
+
80
+ LONGDESC
81
+
82
+
83
+ def gen( yaml_file, template_name=DEAFAULT_TEMPLATE )
84
+
85
+ app = ::AwsMust::AwsMust.new( options )
86
+ app.generate( template_name, yaml_file, options )
87
+
88
+ end
89
+
90
+ end
91
+
92
+ App.start
data/demo/0/conf.yaml ADDED
@@ -0,0 +1 @@
1
+ -- demo 0
@@ -0,0 +1 @@
1
+ {{! empty }}
data/demo/1/conf.yaml ADDED
@@ -0,0 +1 @@
1
+ -- empty
@@ -0,0 +1,22 @@
1
+ {{!
2
+ +++start+++
3
+
4
+ # <a id="top">aws-must demo 1 templates</a>
5
+
6
+ **No documentation yet**
7
+
8
+ +++close+++
9
+ }}
10
+ {
11
+ "AWSTemplateFormatVersion" : "2010-09-09",
12
+ "Description" : "A simple Amazon EC2 instance. Initial copy",
13
+ "Resources" : {
14
+ "MyEC2Instance" : {
15
+ "Type" : "AWS::EC2::Instance",
16
+ "Properties" : {
17
+ "ImageId" : "ami-00dae61d",
18
+ "InstanceType" : "t2.micro"
19
+ }
20
+ }
21
+ }
22
+ }
data/demo/2/conf.yaml ADDED
@@ -0,0 +1,6 @@
1
+ -- demo/2 : added description property
2
+
3
+
4
+ description: "demo/2: a simple Amazon EC2 instance created using
5
+ aws-must tool. Added 'description' tag in
6
+ `root.mustache`"
@@ -0,0 +1,54 @@
1
+ {{!
2
+
3
+ ++start++
4
+
5
+ <style>
6
+ h1 {
7
+ color:blue;
8
+ font-size: 2.5em;
9
+ }
10
+ h2 {
11
+ color:blue;
12
+ font-size: 1.5em;
13
+ }
14
+ body {
15
+ background-color: #b0c4de;
16
+ }
17
+ </style>
18
+
19
+
20
+ # <a id="top">aws-must demo 2 templates</a>
21
+
22
+ ## root.mustache
23
+
24
+ Create an EC2 with following fixed parameters
25
+
26
+ * `ImageId` : "ami-00dae61d",
27
+ * `InstanceType` : "t2.micro"
28
+
29
+ **Attributes**:
30
+
31
+ * `description`: description for the CF template
32
+
33
+ **Actions**:
34
+
35
+ * **Description**: `description`
36
+
37
+
38
+ ++close++
39
+
40
+ }}
41
+
42
+ {
43
+ "AWSTemplateFormatVersion" : "2010-09-09",
44
+ "Description" : "{{description}}",
45
+ "Resources" : {
46
+ "MyEC2Instance" : {
47
+ "Type" : "AWS::EC2::Instance",
48
+ "Properties" : {
49
+ "ImageId" : "ami-00dae61d",
50
+ "InstanceType" : "t2.micro"
51
+ }
52
+ }
53
+ }
54
+ }
data/demo/3/conf.yaml ADDED
@@ -0,0 +1,3 @@
1
+
2
+ description: "demo/3: a simple Amazon EC2 instance created using aws-must tool.
3
+ Resources section created using partial resource.mustache"
@@ -0,0 +1,26 @@
1
+ {{!
2
+
3
+ resources.mustache - fixed resources
4
+
5
+ ++start++
6
+
7
+ ## <a id="resources.mustache"></a>resources.mustache <a class='navigator' href='#top'">[top]</a>
8
+
9
+ Create an EC2 with following fixed parameters
10
+
11
+ * `ImageId` : "ami-00dae61d",
12
+ * `InstanceType` : "t2.micro"
13
+
14
+ ++close++
15
+
16
+
17
+ }}
18
+
19
+
20
+ "MyEC2Instance" : {
21
+ "Type" : "AWS::EC2::Instance",
22
+ "Properties" : {
23
+ "ImageId" : "ami-00dae61d",
24
+ "InstanceType" : "t2.micro"
25
+ }
26
+ }
@@ -0,0 +1,85 @@
1
+ {{!
2
+
3
+
4
+ ==================================================================
5
+ STYLE section
6
+ ==================================================================
7
+
8
+ ++start++
9
+ <style>
10
+ h1 {
11
+ color:blue;
12
+ font-size: 2.5em;
13
+ }
14
+ h2 {
15
+ color:blue;
16
+ font-size: 1.5em;
17
+ }
18
+ body {
19
+ background-color: #b0c4de;
20
+ }
21
+ </style>
22
+ ++close++
23
+
24
+ ==================================================================
25
+ CONTENT section
26
+ ==================================================================
27
+
28
+ ++start++
29
+
30
+ # <a id="top">aws-must demo 3 templates</a>
31
+
32
+ This document is generated automically from `aws-must` -demo
33
+ templates.
34
+
35
+
36
+ Output contains markdown syntax between
37
+ **&plus;&plus;start&plus;&plus;** and
38
+ **&plus;&plus;close&plus;&plus;** -tags from the template files. For
39
+ each template, it
40
+
41
+ * gives a general description of the template
42
+
43
+ * documents the attribute context e.g. `.` or `./resources/Instance`,
44
+ and attributes references of the template
45
+
46
+ * lists template actions, i.e. output from template, or template
47
+ inclusion
48
+
49
+
50
+
51
+ ## <a id="root.mustache"></a>root.mustache <a class='navigator' href='#top'">[top]</a>
52
+
53
+ Create an EC2 instance
54
+
55
+ **Attributes**: context= `.`
56
+
57
+ * `description`: description for the CF template
58
+
59
+ **Actions**:
60
+
61
+ * **Description**: `description`
62
+ * **include** <a href="#resources.mustache">resources.mustache</a>
63
+
64
+ > resources
65
+
66
+ ++close++
67
+
68
+ ==================================================================
69
+
70
+ }}
71
+
72
+ {
73
+ "AWSTemplateFormatVersion" : "2010-09-09",
74
+
75
+ "Description" : "{{description}}",
76
+
77
+
78
+
79
+ "Resources" : {
80
+
81
+ {{> resources }}
82
+
83
+ }
84
+
85
+ }
data/demo/4/conf.yaml ADDED
@@ -0,0 +1,22 @@
1
+ -- demo/2 : added description property
2
+
3
+
4
+ description: "demo/4: a simple Amazon EC2 instance created using aws-must tool.
5
+ The resource created are in defined in YAML configuration, and
6
+ the JSON template should not change."
7
+
8
+
9
+ parameters:
10
+
11
+ - Name: InstanceType
12
+ Type: String
13
+ Description: EC2 reousrce instance type
14
+ Value: &Param_InstanceType t2.micro
15
+
16
+
17
+ resources:
18
+
19
+ - Instance:
20
+ Name: &Resource_1 MyEC2Instance
21
+ ImageId: ami-00dae61d
22
+ InstanceType: *Param_InstanceType
@@ -0,0 +1,27 @@
1
+ {{!
2
+
3
+ resource.mustache
4
+
5
+ ++start++
6
+
7
+ ## <a id="resource.mustache"></a>resource.mustache <a class='navigator' href='#top'">[top]</a>
8
+
9
+ Dispatches resource sub-type templates based resource Type propertys
10
+
11
+ **Attributes**: context= `./resources`
12
+
13
+ * `Instance`: sub-document defining an EC instance
14
+
15
+
16
+ **Actions**:
17
+
18
+ * include <a href="#resourceInstance.mustache">resourceInstance.mustache</a> if `Instance`
19
+
20
+ > resourceInstance
21
+
22
+ ++close++
23
+
24
+
25
+ }}
26
+
27
+ {{# Instance }}{{> resourceInstance}}{{/ Instance }}
@@ -0,0 +1,32 @@
1
+ {{!
2
+
3
+
4
+ ++start++
5
+
6
+ ## <a id="resourceInstance.mustache"></a>resourceInstance.mustache <a class='navigator' href='#top'">[top]</a>
7
+
8
+ Create an EC2 instance
9
+
10
+ **Attributes**: context= `./resources/Instance`
11
+
12
+ * `Name`: name of the EC2 instance to create
13
+ * `ImageId`: AIM id to create
14
+
15
+ **Actions**:
16
+
17
+ * **Name**: `Name`
18
+ * **Type**: 'AWS::EC2::Instance'
19
+ * **ImageId**: `ImageId`
20
+
21
+ ++close++
22
+
23
+ }}
24
+
25
+
26
+ "{{Name}}" : {
27
+ "Type" : "AWS::EC2::Instance",
28
+ "Properties" : {
29
+ "ImageId" : "{{ImageId}}",
30
+ "InstanceType" : "{{InstanceType}}"
31
+ } {{! Propertites }}
32
+ }{{_comma}}
@@ -0,0 +1,25 @@
1
+ {{!
2
+
3
+ ++start++
4
+
5
+ ## resources.mustache
6
+
7
+ Nothing created here
8
+
9
+ ++close++
10
+
11
+
12
+ }}
13
+ {{!
14
+
15
+ Moved to YAML
16
+
17
+ "MyEC2Instance" : {
18
+ "Type" : "AWS::EC2::Instance",
19
+ "Properties" : {
20
+ "ImageId" : "ami-00dae61d",
21
+ "InstanceType" : "t2.micro"
22
+ }
23
+ }
24
+
25
+ }}