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 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
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in aws-cfn-decompiler.gemspec
4
+ gemspec
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,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -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
+
@@ -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
+ }
@@ -0,0 +1,16 @@
1
+ VpcId:
2
+ Value:
3
+ Ref: VPC
4
+ Description: ID of newly created VPC
5
+
6
+ AccessIP:
7
+ Value:
8
+ Ref: AccessIP
9
+ Description: NAT Instance ID
10
+
11
+ VPCCidrIP:
12
+ Value:
13
+ "Fn::GetAtt":
14
+ - VPC
15
+ - CidrBlock
16
+ Description: Cidr IP of the VPC
@@ -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
@@ -0,0 +1,7 @@
1
+ module Aws
2
+ module Cfn
3
+ module DeCompiler
4
+ VERSION = "0.0.2"
5
+ end
6
+ end
7
+ 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: []