aws-cft-tools 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +10 -0
- data/.gitignore +52 -0
- data/.rspec +2 -0
- data/.rubocop.yml +19 -0
- data/.travis.yml +5 -0
- data/.yardopts +1 -0
- data/BEST-PRACTICES.md +136 -0
- data/CONTRIBUTING.md +38 -0
- data/Gemfile +8 -0
- data/LICENSE +15 -0
- data/README.md +118 -0
- data/Rakefile +17 -0
- data/USAGE.adoc +404 -0
- data/aws-cft-tools.gemspec +53 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/code.json +24 -0
- data/exe/aws-cft +176 -0
- data/lib/aws-cft-tools.rb +3 -0
- data/lib/aws_cft_tools.rb +31 -0
- data/lib/aws_cft_tools/aws_enumerator.rb +55 -0
- data/lib/aws_cft_tools/change.rb +66 -0
- data/lib/aws_cft_tools/client.rb +84 -0
- data/lib/aws_cft_tools/client/base.rb +40 -0
- data/lib/aws_cft_tools/client/cft.rb +93 -0
- data/lib/aws_cft_tools/client/cft/changeset_management.rb +109 -0
- data/lib/aws_cft_tools/client/cft/stack_management.rb +85 -0
- data/lib/aws_cft_tools/client/ec2.rb +136 -0
- data/lib/aws_cft_tools/client/templates.rb +84 -0
- data/lib/aws_cft_tools/deletion_change.rb +43 -0
- data/lib/aws_cft_tools/dependency_tree.rb +109 -0
- data/lib/aws_cft_tools/dependency_tree/nodes.rb +71 -0
- data/lib/aws_cft_tools/dependency_tree/variables.rb +37 -0
- data/lib/aws_cft_tools/errors.rb +25 -0
- data/lib/aws_cft_tools/runbook.rb +166 -0
- data/lib/aws_cft_tools/runbook/report.rb +30 -0
- data/lib/aws_cft_tools/runbooks.rb +16 -0
- data/lib/aws_cft_tools/runbooks/common/changesets.rb +30 -0
- data/lib/aws_cft_tools/runbooks/common/templates.rb +38 -0
- data/lib/aws_cft_tools/runbooks/deploy.rb +107 -0
- data/lib/aws_cft_tools/runbooks/deploy/reporting.rb +50 -0
- data/lib/aws_cft_tools/runbooks/deploy/stacks.rb +109 -0
- data/lib/aws_cft_tools/runbooks/deploy/templates.rb +37 -0
- data/lib/aws_cft_tools/runbooks/deploy/threading.rb +37 -0
- data/lib/aws_cft_tools/runbooks/diff.rb +28 -0
- data/lib/aws_cft_tools/runbooks/diff/context.rb +86 -0
- data/lib/aws_cft_tools/runbooks/diff/context/reporting.rb +87 -0
- data/lib/aws_cft_tools/runbooks/hosts.rb +43 -0
- data/lib/aws_cft_tools/runbooks/images.rb +43 -0
- data/lib/aws_cft_tools/runbooks/init.rb +86 -0
- data/lib/aws_cft_tools/runbooks/retract.rb +69 -0
- data/lib/aws_cft_tools/runbooks/retract/templates.rb +44 -0
- data/lib/aws_cft_tools/runbooks/stacks.rb +43 -0
- data/lib/aws_cft_tools/stack.rb +83 -0
- data/lib/aws_cft_tools/template.rb +177 -0
- data/lib/aws_cft_tools/template/dsl_context.rb +14 -0
- data/lib/aws_cft_tools/template/file_system.rb +62 -0
- data/lib/aws_cft_tools/template/metadata.rb +144 -0
- data/lib/aws_cft_tools/template/properties.rb +129 -0
- data/lib/aws_cft_tools/template_set.rb +120 -0
- data/lib/aws_cft_tools/template_set/array_methods.rb +63 -0
- data/lib/aws_cft_tools/template_set/closure.rb +77 -0
- data/lib/aws_cft_tools/template_set/dependencies.rb +55 -0
- data/lib/aws_cft_tools/template_set/each_slice_state.rb +58 -0
- data/lib/aws_cft_tools/version.rb +8 -0
- data/rubycritic.reek +3 -0
- metadata +321 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsCftTools
|
4
|
+
module Runbooks
|
5
|
+
class Retract
|
6
|
+
##
|
7
|
+
# module with methods to manage ordering of templates
|
8
|
+
#
|
9
|
+
module Templates
|
10
|
+
require_relative '../common/templates'
|
11
|
+
|
12
|
+
include Common::Templates
|
13
|
+
|
14
|
+
##
|
15
|
+
# list the templates in-scope for this retraction
|
16
|
+
#
|
17
|
+
# @return [AwsCftTools::TemplateSet]
|
18
|
+
#
|
19
|
+
def templates
|
20
|
+
@templates ||= filtered_templates(client.templates)
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# List the templates that are available for deletion.
|
25
|
+
#
|
26
|
+
# Templates with known dependents that are not in the set will be removed. Note that this does
|
27
|
+
# not capture dependencies between environments.
|
28
|
+
#
|
29
|
+
# @return [AwsCftTools::TemplateSet]
|
30
|
+
def free_templates
|
31
|
+
set = AwsCftTools::TemplateSet.new(templates.in_folder_order(template_folder_order))
|
32
|
+
client.templates.closed_subset(set).reverse
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# @return [Array<String>]
|
37
|
+
#
|
38
|
+
def template_folder_order
|
39
|
+
options[:template_folder_priorities] || []
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsCftTools
|
4
|
+
module Runbooks
|
5
|
+
##
|
6
|
+
# Images - report on available AMIs
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# % aws-cli stacks # list all known stacks
|
10
|
+
# % aws-cli stacks -e QA # list all known stacks tagged for the QA environment
|
11
|
+
# % aws-cli stacks -e QA -r App # list all known stacks tagged for the QA environment and App role
|
12
|
+
#
|
13
|
+
class Stacks < Runbook::Report
|
14
|
+
###
|
15
|
+
# @return [Array<AwsCftTools::Stack>]
|
16
|
+
#
|
17
|
+
def items
|
18
|
+
client.stacks.sort_by(&method(:sort_key))
|
19
|
+
end
|
20
|
+
|
21
|
+
###
|
22
|
+
# @return [Array<String>]
|
23
|
+
#
|
24
|
+
def columns
|
25
|
+
environment_column + role_column + %w[filename created_at name state]
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def sort_key(stack)
|
31
|
+
stack.name
|
32
|
+
end
|
33
|
+
|
34
|
+
def environment_column
|
35
|
+
options[:environment] ? [] : ['environment']
|
36
|
+
end
|
37
|
+
|
38
|
+
def role_column
|
39
|
+
options[:role] ? [] : ['role']
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsCftTools
|
4
|
+
##
|
5
|
+
# Provides a unified interface for accessing information about deployed CloudFormation templates.
|
6
|
+
#
|
7
|
+
class Stack
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
def initialize(aws_stack, aws_client)
|
11
|
+
@aws_client = aws_client
|
12
|
+
@aws_stack = aws_stack
|
13
|
+
end
|
14
|
+
|
15
|
+
def_delegators :@aws_stack, :description
|
16
|
+
def_delegator :@aws_stack, :stack_name, :name
|
17
|
+
def_delegator :@aws_stack, :creation_time, :created_at
|
18
|
+
def_delegator :@aws_stack, :last_updated_time, :updated_at
|
19
|
+
def_delegator :@aws_stack, :stack_status, :state
|
20
|
+
def_delegator :@aws_stack, :stack_id, :id
|
21
|
+
|
22
|
+
###
|
23
|
+
# @return [String] the unparsed body of the template definition
|
24
|
+
#
|
25
|
+
def template_source
|
26
|
+
@template ||= begin
|
27
|
+
resp = @aws_client.get_template(stack_name: name,
|
28
|
+
template_stage: 'Original')
|
29
|
+
resp.template_body
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# @return [Hash] dictionary of tag names and values for the stack
|
35
|
+
#
|
36
|
+
def tags
|
37
|
+
@tags ||= @aws_stack.tags.each_with_object({}) { |tag, hash| hash[tag.key] = tag.value }
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# @return [Hash] mapping of output name with output definition
|
42
|
+
def outputs
|
43
|
+
@outputs ||= build_hashes(@aws_stack.outputs || [], &:output_key)
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# @return [Hash] mapping of parameter name to parameter definition
|
48
|
+
#
|
49
|
+
def parameters
|
50
|
+
@parameters ||= build_hashes(@aws_stack.parameters || [], &:parameter_key)
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# @return [String] the environment of the stack
|
55
|
+
#
|
56
|
+
def environment
|
57
|
+
tags['Environment']
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# @return [String] the role of the stack
|
62
|
+
#
|
63
|
+
def role
|
64
|
+
tags['Role']
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# @return [String] the filename of the stack's template source
|
69
|
+
#
|
70
|
+
def filename
|
71
|
+
@filename ||= begin
|
72
|
+
source = tags['Source']
|
73
|
+
source ? source.sub(%r{^/+}, '') : nil
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def build_hashes(source, &block)
|
80
|
+
source.map(&block).zip(source).to_h
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'erb'
|
5
|
+
require 'pathname'
|
6
|
+
|
7
|
+
module AwsCftTools
|
8
|
+
##
|
9
|
+
# The AwsCftTools::Template class wraps a CloudFormation template source to provide support for various
|
10
|
+
# operations by the toolset.
|
11
|
+
#
|
12
|
+
# == CloudFormation Templates
|
13
|
+
#
|
14
|
+
# As much as possible, this tool uses CloudFormation templates as-is and makes as many inferences as
|
15
|
+
# reasonable. However, some things aren't captured in stock template information.
|
16
|
+
#
|
17
|
+
# @note Stacks should be removed ("retracted") from AWS before they are removed from the set of templates.
|
18
|
+
# Otherwise, they won't be considered in the set of available templates or stacks.
|
19
|
+
#
|
20
|
+
# @todo Fetch templates from deployed stacks and consider them in the dependency tree for removing or
|
21
|
+
# deploying templates in the repo. Flag stacks with no local source to not be updated on deployment.
|
22
|
+
#
|
23
|
+
# @todo Add ability to init to fetch templates from stacks and put them in files.
|
24
|
+
#
|
25
|
+
# === Allowed Environments
|
26
|
+
#
|
27
|
+
# The environments in which a template should be deployed is provided by the +AllowedValues+ key of the
|
28
|
+
# +Environment+ template parameter.
|
29
|
+
#
|
30
|
+
# @example Allowed Environments
|
31
|
+
# ---
|
32
|
+
# Parameters:
|
33
|
+
# Environment:
|
34
|
+
# AllowedValues:
|
35
|
+
# - QA
|
36
|
+
# - Staging
|
37
|
+
# - Production
|
38
|
+
#
|
39
|
+
# === Allowed Regions
|
40
|
+
#
|
41
|
+
# A template can be pinned to a particular region or set of regions by providing a list of values for
|
42
|
+
# the +Region+ key in the template metadata. If no such key is present, then the template can be
|
43
|
+
# deployed or otherwise used in all regions.
|
44
|
+
#
|
45
|
+
# @example Allowed Regions
|
46
|
+
# ---
|
47
|
+
# Metadata:
|
48
|
+
# Region:
|
49
|
+
# - us-east-1
|
50
|
+
# - us-west-1
|
51
|
+
#
|
52
|
+
# === Explicit Template Dependencies
|
53
|
+
#
|
54
|
+
# As much as possible, dependencies between templates are inferred based on exported and imported
|
55
|
+
# values. However, some templates might depend on another template in a way that isn't captured by
|
56
|
+
# these values. For those dependencies, the templates that should be run first can be listed under the
|
57
|
+
# +DependesOn.Templates+ metadata key.
|
58
|
+
#
|
59
|
+
# @example Explicit Template Dependency
|
60
|
+
# ---
|
61
|
+
# Metadata:
|
62
|
+
# DependsOn:
|
63
|
+
# Templates:
|
64
|
+
# - network/peering.yaml
|
65
|
+
#
|
66
|
+
# === Template Parameters
|
67
|
+
#
|
68
|
+
# Rather than require mappings in templates to hold environment-specific values, a template has a
|
69
|
+
# corresponding parameters file that holds the value for the stack parameter for each environment.
|
70
|
+
# This parameters file is in YAML format and passed through ERB before parsing, so it can incorporate
|
71
|
+
# environment variables and other logic into specifying parameter values.
|
72
|
+
#
|
73
|
+
class Template
|
74
|
+
attr_reader :filename
|
75
|
+
|
76
|
+
require_relative 'template/dsl_context'
|
77
|
+
require_relative 'template/file_system'
|
78
|
+
require_relative 'template/metadata'
|
79
|
+
require_relative 'template/properties'
|
80
|
+
|
81
|
+
include FileSystem
|
82
|
+
include Metadata
|
83
|
+
include Properties
|
84
|
+
|
85
|
+
##
|
86
|
+
# @param filename [String] path to template relative to the +template_dir+ path
|
87
|
+
# @param options [Hash] runbook options
|
88
|
+
# @option options [String] :environment environment in which parameters should be fetched
|
89
|
+
# @option options [String] :parameter_dir directory relative to the +root+ path in which parameter files
|
90
|
+
# are found
|
91
|
+
# @option options [Pathname] :root path to the root of the project
|
92
|
+
# @option options [String] :template_dir directory relative to the +root+ path in which template sources
|
93
|
+
# are found
|
94
|
+
#
|
95
|
+
def initialize(filename, options = {})
|
96
|
+
@options = options
|
97
|
+
@filename = filename
|
98
|
+
end
|
99
|
+
|
100
|
+
##
|
101
|
+
# @return [Array<Hash>] template tags suitable for use in deploying a stack
|
102
|
+
#
|
103
|
+
def tags
|
104
|
+
[
|
105
|
+
{ key: 'Environment', value: @options[:environment] },
|
106
|
+
{ key: 'Source', value: ('/' + filename.to_s).gsub(%r{/+}, '/') }
|
107
|
+
] + role_tag
|
108
|
+
end
|
109
|
+
|
110
|
+
##
|
111
|
+
# @return [Hash] parameters to provide to the AWS client to deploy the template
|
112
|
+
#
|
113
|
+
def stack_parameters
|
114
|
+
{
|
115
|
+
stack_name: name,
|
116
|
+
template_body: template_source_for_aws,
|
117
|
+
parameters: hash_to_param_list(parameters || {}),
|
118
|
+
tags: tags
|
119
|
+
}
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def role_tag
|
125
|
+
if role
|
126
|
+
[{ key: 'Role', value: role }]
|
127
|
+
else
|
128
|
+
[]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def hash_to_param_list(hash)
|
133
|
+
hash.map do |key, value|
|
134
|
+
{
|
135
|
+
parameter_key: key.to_s,
|
136
|
+
parameter_value: value_to_string(value),
|
137
|
+
use_previous_value: !value && value != false || value == ''
|
138
|
+
}
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def value_to_string(value)
|
143
|
+
case value
|
144
|
+
when false
|
145
|
+
'false'
|
146
|
+
when true
|
147
|
+
'true'
|
148
|
+
else
|
149
|
+
value ? value.to_s : value
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
##
|
154
|
+
# Looks through the template to find instances of +Fn::ImportValue+
|
155
|
+
#
|
156
|
+
def pull_imports(hash)
|
157
|
+
hash.flat_map do |key, value|
|
158
|
+
value ||= key
|
159
|
+
if %w[Fn::ImportValue ImportValue].include?(key)
|
160
|
+
pull_import(value)
|
161
|
+
elsif value.is_a?(Hash) || value.is_a?(Array)
|
162
|
+
pull_imports(value)
|
163
|
+
else
|
164
|
+
[]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def pull_import(value)
|
170
|
+
if value.is_a?(Hash)
|
171
|
+
[value['Fn::Sub'] || value['Sub'] || value]
|
172
|
+
else
|
173
|
+
[value]
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsCftTools
|
4
|
+
class Template
|
5
|
+
##
|
6
|
+
# Utility module for evaluating ruby dsl templates.
|
7
|
+
#
|
8
|
+
module DSLContext
|
9
|
+
require 'cloudformation-ruby-dsl/cfntemplate'
|
10
|
+
require 'cloudformation-ruby-dsl/spotprice'
|
11
|
+
require 'cloudformation-ruby-dsl/table'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module AwsCftTools
|
6
|
+
class Template
|
7
|
+
##
|
8
|
+
# Manage template and parameter files.
|
9
|
+
#
|
10
|
+
module FileSystem
|
11
|
+
##
|
12
|
+
# Returns the path to the cloud formation template.
|
13
|
+
#
|
14
|
+
# @return [Pathname]
|
15
|
+
def template_file
|
16
|
+
filename_path(:template_dir, filename)
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Returns the path to the template parameters file.
|
21
|
+
#
|
22
|
+
# @return [Pathname]
|
23
|
+
def parameter_file
|
24
|
+
filename_path(:parameter_dir, filename)
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# The unparsed source of the template.
|
29
|
+
#
|
30
|
+
# @return [String]
|
31
|
+
def template_source
|
32
|
+
@template_source ||= @options[:template_content] || read_file(template_file)
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# The unparsed source of the parameters file for this template.
|
37
|
+
#
|
38
|
+
# @return [String]
|
39
|
+
def parameters_source
|
40
|
+
@parameters_source ||= @options[:parameters_content] || read_file(parameter_file)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def read_file(file)
|
46
|
+
file ? file.read : nil
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# Given the filename relative to the template/parameter root and a symbol indicating which type of
|
51
|
+
# file to point to, returns the full path to the file
|
52
|
+
#
|
53
|
+
# @return [Pathname]
|
54
|
+
def filename_path(dir, filename)
|
55
|
+
# we need to check .yaml, .yml, and .json versions
|
56
|
+
filename = filename.to_s.sub(/\.[^.]*$/, '')
|
57
|
+
base = @options[:root] + @options[dir]
|
58
|
+
%w[.yaml .yml .json .rb].map { |ext| base + (filename + ext) }.detect(&:exist?)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module AwsCftTools
|
6
|
+
class Template
|
7
|
+
##
|
8
|
+
# Simple derived information about templates.
|
9
|
+
#
|
10
|
+
module Metadata
|
11
|
+
##
|
12
|
+
# Mapping of filename extensions to content types.
|
13
|
+
#
|
14
|
+
CONTENT_TYPES = {
|
15
|
+
'.json' => 'json',
|
16
|
+
'.rb' => 'dsl',
|
17
|
+
'.yml' => 'yaml',
|
18
|
+
'.yaml' => 'yaml'
|
19
|
+
}.freeze
|
20
|
+
|
21
|
+
##
|
22
|
+
# The type of template content.
|
23
|
+
#
|
24
|
+
# @return [String] One of +dsl+, +json+, or +yaml+.
|
25
|
+
def template_type
|
26
|
+
content_type(template_file)
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Queries if the template source looks like a CloudFormation template.
|
31
|
+
#
|
32
|
+
# @return [Boolean]
|
33
|
+
def template?
|
34
|
+
template && template['AWSTemplateFormatVersion']
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# The name of the stack built by this template.
|
39
|
+
#
|
40
|
+
# @return [String]
|
41
|
+
def name
|
42
|
+
@name ||= @options[:environment] + '-' +
|
43
|
+
filename.to_s.sub(/\.(ya?ml|json|rb)$/, '').split(%r{/}).reverse.join('-')
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# The parsed template as a Ruby data structure.
|
48
|
+
#
|
49
|
+
# @return [Hash]
|
50
|
+
def template
|
51
|
+
@template ||= template_content_for_filename(template_file)
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# The JSON or YAML source that can be submitted to AWS to build the stack.
|
56
|
+
#
|
57
|
+
# @return [String]
|
58
|
+
def template_source_for_aws
|
59
|
+
template_type == 'dsl' ? JSON.pretty_generate(template) : template_source
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# The parsed parameters for this template in the deployment environment.
|
64
|
+
#
|
65
|
+
# @return [Hash]
|
66
|
+
def parameters
|
67
|
+
@parameters ||= parameters_for_filename_and_environment(parameters_source, @options[:environment])
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def content_type(file)
|
73
|
+
CONTENT_TYPES[file.extname] if file
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Loads the contents of the full path and returns the content as a Ruby data structure
|
78
|
+
#
|
79
|
+
# @return [String]
|
80
|
+
def template_content_for_filename(file)
|
81
|
+
type = content_type(file)
|
82
|
+
return {} unless type
|
83
|
+
send(:"template_content_for_#{type}!")
|
84
|
+
rescue => exception
|
85
|
+
raise AwsCftTools::ParseException, "Error while parsing #{template_file}: #{exception}"
|
86
|
+
end
|
87
|
+
|
88
|
+
def template_content_for_yaml!
|
89
|
+
YAML.safe_load(template_source, [Date], [], true) || {}
|
90
|
+
end
|
91
|
+
|
92
|
+
def template_content_for_json!
|
93
|
+
JSON.parse(template_source) || {}
|
94
|
+
end
|
95
|
+
|
96
|
+
def template_content_for_dsl!
|
97
|
+
with_environment { JSON.parse(DSLContext.module_eval(template_source).to_json) }
|
98
|
+
end
|
99
|
+
|
100
|
+
##
|
101
|
+
# Loads the contents of the full path and passes it through ERB before parsing as YAML. Returns
|
102
|
+
# a Ruby structure.
|
103
|
+
#
|
104
|
+
# If no file exists, then a simple hash with the +Environment+ key set.
|
105
|
+
#
|
106
|
+
def parameters_for_filename_and_environment(param_source, env)
|
107
|
+
parameters_for_filename_and_environment!(param_source, env)
|
108
|
+
rescue AwsCftTools::ToolingException
|
109
|
+
raise
|
110
|
+
rescue => exception
|
111
|
+
raise AwsCftTools::ParseException, "Error while reading and parsing #{parameter_file}: #{exception}"
|
112
|
+
end
|
113
|
+
|
114
|
+
def parameters_for_filename_and_environment!(param_source, env)
|
115
|
+
return { Environment: env } unless param_source
|
116
|
+
|
117
|
+
params = YAML.safe_load(process_erb_file(param_source), [], [], true)[env] || {}
|
118
|
+
params.update(Environment: env)
|
119
|
+
end
|
120
|
+
|
121
|
+
def process_erb_file(content)
|
122
|
+
with_environment { ERB.new(content).result }
|
123
|
+
end
|
124
|
+
|
125
|
+
def with_environment
|
126
|
+
return unless block_given?
|
127
|
+
prior = ENV.to_h
|
128
|
+
ENV.update(aws_env)
|
129
|
+
yield
|
130
|
+
ensure
|
131
|
+
ENV.update(prior)
|
132
|
+
end
|
133
|
+
|
134
|
+
def aws_env
|
135
|
+
region = @options[:region]
|
136
|
+
{
|
137
|
+
'AWS_REGION' => region,
|
138
|
+
'EC2_REGION' => region,
|
139
|
+
'AWS_PROFILE' => @options[:profile]
|
140
|
+
}
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|