aws-cfn-decompiler 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +24 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +35 -0
- data/Rakefile +2 -0
- data/aws-cfn-decompiler.gemspec +30 -0
- data/aws-cfn-decompiler.iml +31 -0
- data/bin/cfn-decompiler +28 -0
- data/example/mappings/alinux.json +11 -0
- data/example/mappings/instance_types.json +14 -0
- data/example/mappings/nat.json +11 -0
- data/example/outputs.yml +16 -0
- data/example/params.json +36 -0
- data/example/resources/gateway.json +18 -0
- data/example/resources/instances/app.yml +15 -0
- data/example/resources/instances/bastion.json +20 -0
- data/example/resources/instances/nat.json +12 -0
- data/example/resources/route53.json +16 -0
- data/example/resources/routing.json +32 -0
- data/example/resources/security_groups.json +54 -0
- data/example/resources/subnets.json +35 -0
- data/example/resources/vpc.json +11 -0
- data/lib/aws/cfn/decompiler.rb +124 -0
- data/lib/aws/cfn/decompiler/version.rb +7 -0
- metadata +178 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4888b72116897780eaedbed128dbfe3b692fdb30
|
4
|
+
data.tar.gz: a57c7337752b17187265c483798ea0a9722f5e3a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c09ec7e8ee54dcbea350b683c357c4f9f53efabfbe86fc2e4045b14947cc946a1a347a259362af5d8311d6a7be3ddc1840bdeffd3f5caf9941a27849fd4d9ec4
|
7
|
+
data.tar.gz: e9af2f47f2e2aeada6387dc97d0c344fe7cf7f59447286bc20cd7aebc7395e54a0444910a457d113c4ee50d569726c20467f7a4e1820eee09d0131268f8d84f5
|
data/.gitignore
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
compiled.json
|
24
|
+
Gemfile.lock
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
aws-cfn-decompiler
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.9.3
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Christo DeLange
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
aws-cfn-compiler
|
2
|
+
================
|
3
|
+
|
4
|
+
A simple script to compile and perform some validation for CloudFormation scripts. The idea is to create a folder structure to better manage pieces of a CloudFormation deployment. Additionally, writing in JSON is hard, so the compiler takes YAML files as well.
|
5
|
+
|
6
|
+
|
7
|
+
Installation
|
8
|
+
------------
|
9
|
+
|
10
|
+
gem install bundler
|
11
|
+
bundle install
|
12
|
+
|
13
|
+
Usage
|
14
|
+
-----
|
15
|
+
|
16
|
+
```
|
17
|
+
./compile.rb -d ROOT_DIRECTORY -o OUTPUT_JSON_FILE
|
18
|
+
```
|
19
|
+
|
20
|
+
Directory Structure
|
21
|
+
-------------------
|
22
|
+
|
23
|
+
The pieces of the CloudFormation script is split into four groups:
|
24
|
+
|
25
|
+
* Parameters
|
26
|
+
* Mappings
|
27
|
+
* Resources
|
28
|
+
* Outputs
|
29
|
+
|
30
|
+
For each group, you can define a single file at the root directory with that name (i.e. outputs.json or outputs.yml) or a directory with that name containing any structure of JSON or YAML files (i.e. resources/nat.yml or resources/app/hello.json). The script is responsible for combining everything into one JSON file.
|
31
|
+
|
32
|
+
Reference Validation
|
33
|
+
--------------------
|
34
|
+
|
35
|
+
After all the pieces are stiched together, the system runs through the file finding references to names and then attempt to validate that those names exist in the file.
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'aws/cfn/decompiler/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "aws-cfn-decompiler"
|
8
|
+
spec.version = Aws::Cfn::DeCompiler::VERSION
|
9
|
+
spec.authors = ["Christo De Lange"]
|
10
|
+
spec.email = ["rubygems@dldinternet.com"]
|
11
|
+
spec.summary = %q{A simple script to decompile and produce reusable components for CloudFormation templates.}
|
12
|
+
spec.description = %q{The idea is to extract a big CloudFormation template into a folder structure to better manage pieces of a CloudFormation deployment. Additionally, writing in JSON is hard, so the decompiler can create YAML files as well.}
|
13
|
+
spec.homepage = "https://github.com/dldinternet/aws-cfn-decompiler"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "awesome_print"
|
22
|
+
spec.add_dependency "slop"
|
23
|
+
spec.add_dependency "psych"
|
24
|
+
spec.add_dependency "json"
|
25
|
+
# spec.add_dependency "yajl-ruby"
|
26
|
+
spec.add_dependency 'aws-cfn-compiler', '>= 0.1.0', '~> 0.1'
|
27
|
+
|
28
|
+
spec.add_development_dependency 'bundler', "~> 1.6"
|
29
|
+
spec.add_development_dependency 'rake'
|
30
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<module type="RUBY_MODULE" version="4">
|
3
|
+
<component name="CompassSettings">
|
4
|
+
<option name="compassSupportEnabled" value="true" />
|
5
|
+
</component>
|
6
|
+
<component name="FacetManager">
|
7
|
+
<facet type="gem" name="Ruby Gem">
|
8
|
+
<configuration>
|
9
|
+
<option name="GEM_APP_ROOT_PATH" value="$MODULE_DIR$" />
|
10
|
+
<option name="GEM_APP_TEST_PATH" value="$MODULE_DIR$/test" />
|
11
|
+
<option name="GEM_APP_LIB_PATH" value="$MODULE_DIR$/lib" />
|
12
|
+
</configuration>
|
13
|
+
</facet>
|
14
|
+
</component>
|
15
|
+
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
16
|
+
<exclude-output />
|
17
|
+
<content url="file://$MODULE_DIR$">
|
18
|
+
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
19
|
+
</content>
|
20
|
+
<orderEntry type="jdk" jdkName="RVM: ruby-1.9.3-p547 [aws-cfn-decompiler]" jdkType="RUBY_SDK" />
|
21
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
22
|
+
<orderEntry type="library" scope="PROVIDED" name="awesome_print (v1.2.0, RVM: ruby-1.9.3-p547 [aws-cfn-decompiler]) [gem]" level="application" />
|
23
|
+
<orderEntry type="library" scope="PROVIDED" name="aws-cfn-compiler (v0.1.0, RVM: ruby-1.9.3-p547 [aws-cfn-decompiler]) [gem]" level="application" />
|
24
|
+
<orderEntry type="library" scope="PROVIDED" name="bundler (v1.6.2, RVM: ruby-1.9.3-p547 [aws-cfn-decompiler]) [gem]" level="application" />
|
25
|
+
<orderEntry type="library" scope="PROVIDED" name="json (v1.8.1, RVM: ruby-1.9.3-p547 [aws-cfn-decompiler]) [gem]" level="application" />
|
26
|
+
<orderEntry type="library" scope="PROVIDED" name="psych (v2.0.5, RVM: ruby-1.9.3-p547 [aws-cfn-decompiler]) [gem]" level="application" />
|
27
|
+
<orderEntry type="library" scope="PROVIDED" name="rake (v10.3.2, RVM: ruby-1.9.3-p547 [aws-cfn-decompiler]) [gem]" level="application" />
|
28
|
+
<orderEntry type="library" scope="PROVIDED" name="slop (v3.5.0, RVM: ruby-1.9.3-p547 [aws-cfn-decompiler]) [gem]" level="application" />
|
29
|
+
</component>
|
30
|
+
</module>
|
31
|
+
|
data/bin/cfn-decompiler
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
# require 'safe_yaml'
|
6
|
+
# SafeYAML::OPTIONS[:default_mode] = :safe
|
7
|
+
|
8
|
+
# Borrowing from "whiches" gem ...
|
9
|
+
cmd = File.basename(__FILE__, '.rb')
|
10
|
+
exes = []
|
11
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
12
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
13
|
+
exts.each { |ext|
|
14
|
+
exe = File.join(path, "#{cmd}#{ext}")
|
15
|
+
exes << exe if File.executable? exe
|
16
|
+
}
|
17
|
+
end
|
18
|
+
path = if exes.size > 0
|
19
|
+
File.dirname(exes[0])
|
20
|
+
else
|
21
|
+
File.dirname(__FILE__)
|
22
|
+
end
|
23
|
+
|
24
|
+
add_path = File.expand_path(File.join(path, "..", "lib"))
|
25
|
+
$:.unshift(add_path)
|
26
|
+
|
27
|
+
require 'aws/cfn/decompiler'
|
28
|
+
Aws::Cfn::DeCompiler::Main.new().run
|
@@ -0,0 +1,11 @@
|
|
1
|
+
{
|
2
|
+
"AWSRegionArch2AMI" : {
|
3
|
+
"us-east-1" : { "64" : "ami-1624987f" },
|
4
|
+
"us-west-1" : { "64" : "ami-1bf9de5e" },
|
5
|
+
"us-west-2" : { "64" : "ami-2a31bf1a" },
|
6
|
+
"eu-west-1" : { "64" : "ami-c37474b7" },
|
7
|
+
"sa-east-1" : { "64" : "ami-1e08d103" },
|
8
|
+
"ap-southeast-1" : { "64" : "ami-a6a7e7f4" },
|
9
|
+
"ap-northeast-1" : { "64" : "ami-4e6cd34f" }
|
10
|
+
}
|
11
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
{
|
2
|
+
"AWSInstanceType2Arch" : {
|
3
|
+
"t1.micro" : { "Arch" : "64" },
|
4
|
+
"m1.small" : { "Arch" : "64" },
|
5
|
+
"m1.medium" : { "Arch" : "64" },
|
6
|
+
"m1.large" : { "Arch" : "64" },
|
7
|
+
"m1.xlarge" : { "Arch" : "64" },
|
8
|
+
"m2.xlarge" : { "Arch" : "64" },
|
9
|
+
"m2.2xlarge" : { "Arch" : "64" },
|
10
|
+
"m2.4xlarge" : { "Arch" : "64" },
|
11
|
+
"c1.medium" : { "Arch" : "64" },
|
12
|
+
"c1.xlarge" : { "Arch" : "64" }
|
13
|
+
}
|
14
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
{
|
2
|
+
"AWSRegionArch2AMINAT" : {
|
3
|
+
"us-east-1" : { "64" : "ami-f619c29f" },
|
4
|
+
"us-west-1" : { "64" : "ami-3bcc9e7e" },
|
5
|
+
"us-west-2" : { "64" : "ami-52ff7262" },
|
6
|
+
"eu-west-1" : { "64" : "ami-e5e2d991" },
|
7
|
+
"sa-east-1" : { "64" : "ami-0039e61d" },
|
8
|
+
"ap-southeast-1" : { "64" : "ami-02eb9350" },
|
9
|
+
"ap-northeast-1" : { "64" : "ami-14d86d15" }
|
10
|
+
}
|
11
|
+
}
|
data/example/outputs.yml
ADDED
data/example/params.json
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
{ "VPCPrefix" : {
|
2
|
+
"Description" : "IP Prefix for VPC (xxx.xxx)",
|
3
|
+
"Type" : "String",
|
4
|
+
"MinLength": "1",
|
5
|
+
"MaxLength": "64",
|
6
|
+
"AllowedPattern" : "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",
|
7
|
+
"ConstraintDescription" : "First two numbers for an IP"
|
8
|
+
},
|
9
|
+
|
10
|
+
"URLSubfix" : {
|
11
|
+
"Description" : "Additional component of the URL: app.[URLSubfix.][hostedZoneName]",
|
12
|
+
"Type" : "String",
|
13
|
+
"MinLength": "0",
|
14
|
+
"MaxLength": "64",
|
15
|
+
"AllowedPattern" : "([a-z0-9_\-]+\.|)",
|
16
|
+
"ConstraintDescription" : "Must be alphanumerics, underscore, or dash and end in a dot or may be blank"
|
17
|
+
},
|
18
|
+
|
19
|
+
"Route53HostedZoneName" : {
|
20
|
+
"Description" : "Name of the hosted zone (i.e. myapp.com)",
|
21
|
+
"Type" : "String",
|
22
|
+
"MinLength": "3",
|
23
|
+
"MaxLength": "64",
|
24
|
+
"AllowedPattern" : "[a-z0-9_\-\.]+",
|
25
|
+
"ConstraintDescription" : "Must be alphanumerics, underscores, dashes, or dots"
|
26
|
+
},
|
27
|
+
|
28
|
+
"KeyName" : {
|
29
|
+
"Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances",
|
30
|
+
"Type" : "String",
|
31
|
+
"MinLength": "1",
|
32
|
+
"MaxLength": "64",
|
33
|
+
"AllowedPattern" : "[-_ a-zA-Z0-9]*",
|
34
|
+
"ConstraintDescription" : "can contain only alphanumeric characters, spaces, dashes and underscores."
|
35
|
+
}
|
36
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
{ "InternetGateway" : {
|
2
|
+
"Type" : "AWS::EC2::InternetGateway",
|
3
|
+
"Properties" : {
|
4
|
+
"Tags" : [
|
5
|
+
{"Key" : "Application", "Value" : { "Ref" : "AWS::StackName"} },
|
6
|
+
{"Key" : "Network", "Value" : "Public" }
|
7
|
+
]
|
8
|
+
}
|
9
|
+
},
|
10
|
+
|
11
|
+
"AttachGateway" : {
|
12
|
+
"Type" : "AWS::EC2::VPCGatewayAttachment",
|
13
|
+
"Properties" : {
|
14
|
+
"VpcId" : { "Ref" : "VPC" },
|
15
|
+
"InternetGatewayId" : { "Ref" : "InternetGateway" }
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
AppServer:
|
2
|
+
Type: AWS::EC2::Instance
|
3
|
+
Properties:
|
4
|
+
InstanceType: t1.micro
|
5
|
+
KeyName:
|
6
|
+
Ref: KeyName
|
7
|
+
SubnetId:
|
8
|
+
Ref: PublicASubnet
|
9
|
+
ImageId:
|
10
|
+
"Fn::FindInMap":
|
11
|
+
- AWSRegionArch2AMI
|
12
|
+
- Ref: AWS::Region
|
13
|
+
- 64
|
14
|
+
SecurityGroupIds:
|
15
|
+
- Ref: AppSG
|
@@ -0,0 +1,20 @@
|
|
1
|
+
{ "AccessIP" : {
|
2
|
+
"Type" : "AWS::EC2::EIP",
|
3
|
+
"Properties" : {
|
4
|
+
"Domain" : "vpc",
|
5
|
+
"InstanceId" : { "Ref" : "AccessA1" }
|
6
|
+
}
|
7
|
+
},
|
8
|
+
|
9
|
+
"AccessA1" : {
|
10
|
+
"Type" : "AWS::EC2::Instance",
|
11
|
+
|
12
|
+
"Properties" : {
|
13
|
+
"InstanceType" : "m1.small",
|
14
|
+
"ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, "64" ]},
|
15
|
+
"SecurityGroupIds" : [{ "Ref" : "AccessSG" }],
|
16
|
+
"SubnetId" : { "Ref" : "PublicASubnet" },
|
17
|
+
"KeyName" : { "Ref" : "KeyName" }
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
{ "NATDevice" : {
|
2
|
+
"Type" : "AWS::EC2::Instance",
|
3
|
+
"Properties" : {
|
4
|
+
"InstanceType" : "t1.micro",
|
5
|
+
"KeyName" : { "Ref" : "KeyName" },
|
6
|
+
"SubnetId" : { "Ref" : "PublicASubnet" },
|
7
|
+
"SourceDestCheck" : "false",
|
8
|
+
"ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMINAT", { "Ref" : "AWS::Region" }, "64" ]},
|
9
|
+
"SecurityGroupIds" : [{ "Ref" : "NATSG" }]
|
10
|
+
}
|
11
|
+
}
|
12
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
{ "Route53" : {
|
2
|
+
"Type" : "AWS::Route53::RecordSetGroup",
|
3
|
+
"Properties" : {
|
4
|
+
"HostedZoneName" : {"Ref" : "Route53HostedZoneName"},
|
5
|
+
"RecordSets" : [
|
6
|
+
{ "Type" : "AWS::Route53::RecordSet",
|
7
|
+
"Properties" : {
|
8
|
+
"Name" : {"Fn::Join" : [ "", "app.", [{"Ref" : "URLSubfix"}] ]},
|
9
|
+
"Type" : "A",
|
10
|
+
"AliasTarget" : "AppELB"
|
11
|
+
}
|
12
|
+
}
|
13
|
+
]
|
14
|
+
}
|
15
|
+
}
|
16
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
{ "PublicRouteTable" : {
|
2
|
+
"Type" : "AWS::EC2::RouteTable",
|
3
|
+
"Properties" : {
|
4
|
+
"VpcId" : {"Ref" : "VPC"}
|
5
|
+
}
|
6
|
+
},
|
7
|
+
|
8
|
+
"PublicRoute" : {
|
9
|
+
"Type" : "AWS::EC2::Route",
|
10
|
+
"Properties" : {
|
11
|
+
"RouteTableId" : { "Ref" : "PublicRouteTable" },
|
12
|
+
"DestinationCidrBlock" : "0.0.0.0/0",
|
13
|
+
"GatewayId" : { "Ref" : "InternetGateway" }
|
14
|
+
}
|
15
|
+
},
|
16
|
+
|
17
|
+
"PrivateRouteTable" : {
|
18
|
+
"Type" : "AWS::EC2::RouteTable",
|
19
|
+
"Properties" : {
|
20
|
+
"VpcId" : {"Ref" : "VPC"}
|
21
|
+
}
|
22
|
+
},
|
23
|
+
|
24
|
+
"PrivateRoute" : {
|
25
|
+
"Type" : "AWS::EC2::Route",
|
26
|
+
"Properties" : {
|
27
|
+
"RouteTableId" : { "Ref" : "PrivateRouteTable" },
|
28
|
+
"DestinationCidrBlock" : "0.0.0.0/0",
|
29
|
+
"InstanceId" : { "Ref" : "NATDevice" }
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
{ "AccessSG" : {
|
2
|
+
"Type" : "AWS::EC2::SecurityGroup",
|
3
|
+
"Properties" : {
|
4
|
+
"VpcId" : { "Ref" : "VPC" },
|
5
|
+
"GroupDescription" : "Enable SSH access via port 22",
|
6
|
+
"SecurityGroupIngress" : [ { "IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : "0.0.0.0/0" } ]
|
7
|
+
}
|
8
|
+
},
|
9
|
+
|
10
|
+
"NATSG" : {
|
11
|
+
"Type" : "AWS::EC2::SecurityGroup",
|
12
|
+
"Properties" : {
|
13
|
+
"GroupDescription" : "Enable internal access to the NAT device",
|
14
|
+
"VpcId" : { "Ref" : "VPC" },
|
15
|
+
"SecurityGroupIngress" : [
|
16
|
+
{ "IpProtocol" : "tcp", "FromPort" : "0", "ToPort" : "65535", "CidrIp" : {"Fn::Join" : [ ".", [{"Ref" : "VPCPrefix"}, "0", "0/16"] ]} } ,
|
17
|
+
{ "IpProtocol" : "udp", "FromPort" : "0", "ToPort" : "65535", "CidrIp" : {"Fn::Join" : [ ".", [{"Ref" : "VPCPrefix"}, "0", "0/16"] ]} } ,
|
18
|
+
{ "IpProtocol" : "icmp", "FromPort" : "-1", "ToPort" : "-1", "CidrIp" : {"Fn::Join" : [ ".", [{"Ref" : "VPCPrefix"}, "0", "0/16"] ]} }
|
19
|
+
],
|
20
|
+
"SecurityGroupEgress" : [
|
21
|
+
{ "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0" } ,
|
22
|
+
{ "IpProtocol" : "tcp", "FromPort" : "443", "ToPort" : "443", "CidrIp" : "0.0.0.0/0" },
|
23
|
+
{ "IpProtocol" : "tcp", "FromPort" : "0", "ToPort" : "65535", "CidrIp" : {"Fn::Join" : [ ".", [{"Ref" : "VPCPrefix"}, "0", "0/16"] ]} },
|
24
|
+
{ "IpProtocol" : "icmp", "FromPort" : "-1", "ToPort" : "-1", "CidrIp" : "0.0.0.0/0" }
|
25
|
+
]
|
26
|
+
}
|
27
|
+
},
|
28
|
+
|
29
|
+
"AppSG" : {
|
30
|
+
"Type" : "AWS::EC2::SecurityGroup",
|
31
|
+
"Properties" : {
|
32
|
+
"GroupDescription" : "Application Server Security Group",
|
33
|
+
"VpcId" : { "Ref" : "VPC" },
|
34
|
+
"SecurityGroupIngress" : [
|
35
|
+
{ "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "SourceSecurityGroupName" : "AppELBSG" },
|
36
|
+
{ "IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "SourceSecurityGroupName" : "AccessSG" }
|
37
|
+
]
|
38
|
+
}
|
39
|
+
},
|
40
|
+
|
41
|
+
"AppELBSG" : {
|
42
|
+
"Type" : "AWS::EC2::SecurityGroup",
|
43
|
+
"Properties" : {
|
44
|
+
"VpcId" : { "Ref" : "VPC" },
|
45
|
+
"GroupDescription" : "Elastic Load Balancing for App Servers",
|
46
|
+
"SecurityGroupIngress" : [
|
47
|
+
{ "IpProtocol" : "tcp", "FromPort" : "443", "ToPort" : "443", "CidrIp" : "0.0.0.0/0" }
|
48
|
+
],
|
49
|
+
"SecurityGroupEgress" : [
|
50
|
+
{ "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "SourceSecurityGroupName" : "AppSG" }
|
51
|
+
]
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
{
|
2
|
+
"PublicASubnet" : {
|
3
|
+
"Type" : "AWS::EC2::Subnet",
|
4
|
+
"Properties" : {
|
5
|
+
"VpcId" : { "Ref" : "VPC" },
|
6
|
+
"AvailabilityZone" : "us-east-1a",
|
7
|
+
"CidrBlock" : {"Fn::Join" : [ ".", [{"Ref" : "VPCPrefix"}, "1", "0/24"] ]}
|
8
|
+
}
|
9
|
+
},
|
10
|
+
|
11
|
+
"PrivateASubnet" : {
|
12
|
+
"Type" : "AWS::EC2::Subnet",
|
13
|
+
"Properties" : {
|
14
|
+
"VpcId" : { "Ref" : "VPC" },
|
15
|
+
"AvailabilityZone" : "us-east-1a",
|
16
|
+
"CidrBlock" : {"Fn::Join" : [ ".", [{"Ref" : "VPCPrefix"}, "101", "0/24"] ]}
|
17
|
+
}
|
18
|
+
},
|
19
|
+
|
20
|
+
"PublicSubnetARouteTableAssociation" : {
|
21
|
+
"Type" : "AWS::EC2::SubnetRouteTableAssociation",
|
22
|
+
"Properties" : {
|
23
|
+
"SubnetId" : { "Ref" : "PublicASubnet" },
|
24
|
+
"RouteTableId" : { "Ref" : "PublicRouteTable" }
|
25
|
+
}
|
26
|
+
},
|
27
|
+
|
28
|
+
"PrivateSubnetARouteTableAssociation" : {
|
29
|
+
"Type" : "AWS::EC2::SubnetRouteTableAssociation",
|
30
|
+
"Properties" : {
|
31
|
+
"SubnetId" : { "Ref" : "PrivateASubnet" },
|
32
|
+
"RouteTableId" : { "Ref" : "PrivateRouteTable" }
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
{ "VPC" : {
|
2
|
+
"Type" : "AWS::EC2::VPC",
|
3
|
+
"Properties" : {
|
4
|
+
"CidrBlock" : {"Fn::Join" : [ ".", [{"Ref" : "VPCPrefix"}, "0.0/16"] ]},
|
5
|
+
"Tags" : [
|
6
|
+
{"Key" : "Application", "Value" : { "Ref" : "AWS::StackName"} },
|
7
|
+
{"Key" : "Network", "Value" : "Public" }
|
8
|
+
]
|
9
|
+
}
|
10
|
+
}
|
11
|
+
}
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require "aws/cfn/decompiler/version"
|
2
|
+
require "aws/cfn/compiler"
|
3
|
+
|
4
|
+
require 'json'
|
5
|
+
require 'ap'
|
6
|
+
require 'yaml'
|
7
|
+
require 'slop'
|
8
|
+
|
9
|
+
module Aws
|
10
|
+
module Cfn
|
11
|
+
module DeCompiler
|
12
|
+
class Main < Aws::Cfn::Compiler::Main
|
13
|
+
attr_accessor :template
|
14
|
+
|
15
|
+
def run
|
16
|
+
|
17
|
+
@opts = Slop.parse(help: true, strict: true) do
|
18
|
+
on :j, :template=, 'The template to decompile', as: String
|
19
|
+
on :o, :output=, 'The directory to output the components to.', as: String
|
20
|
+
on :f, :format=, 'The output format of the components. [JSON|YAML]', as: String, match: %r/yaml|json/i
|
21
|
+
on :s, :specification=, 'The specification file to create.', as: String
|
22
|
+
end
|
23
|
+
|
24
|
+
unless @opts[:template]
|
25
|
+
puts @opts
|
26
|
+
exit
|
27
|
+
end
|
28
|
+
unless @opts[:output].nil?
|
29
|
+
unless File.directory?(@opts[:output])
|
30
|
+
puts @opts
|
31
|
+
exit
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
load @opts[:template]
|
36
|
+
|
37
|
+
puts
|
38
|
+
puts 'Validating decompiled file...'
|
39
|
+
|
40
|
+
validate(@items)
|
41
|
+
|
42
|
+
output_dir = @opts[:output] || Dir.pwd
|
43
|
+
puts
|
44
|
+
puts "Writing decompiled parts to #{output_dir}..."
|
45
|
+
save(output_dir)
|
46
|
+
|
47
|
+
puts
|
48
|
+
puts '*** Decompiled Successfully ***'
|
49
|
+
end
|
50
|
+
|
51
|
+
def save(output_dir)
|
52
|
+
|
53
|
+
format = @opts[:format] rescue 'yaml'
|
54
|
+
[ :Mappings, :Parameters, :Resources, :Outputs ].each do |section|
|
55
|
+
|
56
|
+
@items[section].each do |name,value|
|
57
|
+
dir = File.join(output_dir,section.to_s)
|
58
|
+
unless File.directory?(dir)
|
59
|
+
Dir.mkdir(dir)
|
60
|
+
end
|
61
|
+
file = "#{name}.#{format}"
|
62
|
+
path = File.join(dir,file)
|
63
|
+
|
64
|
+
begin
|
65
|
+
File.delete path if File.exists? path
|
66
|
+
File.open path, 'w' do |f|
|
67
|
+
case format
|
68
|
+
when /json/
|
69
|
+
f.write JSON.pretty_generate(compiled)
|
70
|
+
when /yaml/
|
71
|
+
f.write value.to_yaml line_width: 1024, indentation: 4, canonical: false
|
72
|
+
else
|
73
|
+
raise "Unsupported format #{format}. Should have noticed this earlier!"
|
74
|
+
end
|
75
|
+
f.close
|
76
|
+
end
|
77
|
+
puts " decompiled #{section}/#{file}."
|
78
|
+
rescue
|
79
|
+
puts "!!! Could not write compiled file #{path}: #{$!}"
|
80
|
+
abort!
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def load(file=nil)
|
88
|
+
if file
|
89
|
+
begin
|
90
|
+
abs = File.absolute_path(File.expand_path(file))
|
91
|
+
unless File.exists?(abs) or @opts[:output].nil?
|
92
|
+
abs = File.absolute_path(File.expand_path(File.join(@opts[:output],file)))
|
93
|
+
end
|
94
|
+
rescue
|
95
|
+
# pass
|
96
|
+
end
|
97
|
+
if File.exists?(abs)
|
98
|
+
case File.extname(File.basename(abs)).downcase
|
99
|
+
when /json/
|
100
|
+
template = JSON.parse(File.read(abs))
|
101
|
+
when /yaml/
|
102
|
+
template = YAML.load(File.read(abs))
|
103
|
+
else
|
104
|
+
raise "Unsupported file type for specification: #{file}"
|
105
|
+
end
|
106
|
+
#@items = template
|
107
|
+
|
108
|
+
template.each {|key,val|
|
109
|
+
@items[key.to_sym] = val
|
110
|
+
}
|
111
|
+
|
112
|
+
else
|
113
|
+
raise "Unable to open template: #{abs}"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
protected
|
119
|
+
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
metadata
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aws-cfn-decompiler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Christo De Lange
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: awesome_print
|
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
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: slop
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: psych
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: json
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: aws-cfn-compiler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.1.0
|
76
|
+
- - "~>"
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0.1'
|
79
|
+
type: :runtime
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 0.1.0
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0.1'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: bundler
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '1.6'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '1.6'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: rake
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
description: The idea is to extract a big CloudFormation template into a folder structure
|
118
|
+
to better manage pieces of a CloudFormation deployment. Additionally, writing in
|
119
|
+
JSON is hard, so the decompiler can create YAML files as well.
|
120
|
+
email:
|
121
|
+
- rubygems@dldinternet.com
|
122
|
+
executables:
|
123
|
+
- cfn-decompiler
|
124
|
+
extensions: []
|
125
|
+
extra_rdoc_files: []
|
126
|
+
files:
|
127
|
+
- ".gitignore"
|
128
|
+
- ".ruby-gemset"
|
129
|
+
- ".ruby-version"
|
130
|
+
- Gemfile
|
131
|
+
- LICENSE.txt
|
132
|
+
- README.md
|
133
|
+
- Rakefile
|
134
|
+
- aws-cfn-decompiler.gemspec
|
135
|
+
- aws-cfn-decompiler.iml
|
136
|
+
- bin/cfn-decompiler
|
137
|
+
- example/mappings/alinux.json
|
138
|
+
- example/mappings/instance_types.json
|
139
|
+
- example/mappings/nat.json
|
140
|
+
- example/outputs.yml
|
141
|
+
- example/params.json
|
142
|
+
- example/resources/gateway.json
|
143
|
+
- example/resources/instances/app.yml
|
144
|
+
- example/resources/instances/bastion.json
|
145
|
+
- example/resources/instances/nat.json
|
146
|
+
- example/resources/route53.json
|
147
|
+
- example/resources/routing.json
|
148
|
+
- example/resources/security_groups.json
|
149
|
+
- example/resources/subnets.json
|
150
|
+
- example/resources/vpc.json
|
151
|
+
- lib/aws/cfn/decompiler.rb
|
152
|
+
- lib/aws/cfn/decompiler/version.rb
|
153
|
+
homepage: https://github.com/dldinternet/aws-cfn-decompiler
|
154
|
+
licenses:
|
155
|
+
- MIT
|
156
|
+
metadata: {}
|
157
|
+
post_install_message:
|
158
|
+
rdoc_options: []
|
159
|
+
require_paths:
|
160
|
+
- lib
|
161
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
167
|
+
requirements:
|
168
|
+
- - ">="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: '0'
|
171
|
+
requirements: []
|
172
|
+
rubyforge_project:
|
173
|
+
rubygems_version: 2.2.2
|
174
|
+
signing_key:
|
175
|
+
specification_version: 4
|
176
|
+
summary: A simple script to decompile and produce reusable components for CloudFormation
|
177
|
+
templates.
|
178
|
+
test_files: []
|