Module: SparkleFormation::Provider::Terraform

Defined in:
lib/sparkle_formation/provider/terraform.rb

Overview

Terraform specific implementation

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(klass) ⇒ Object

Properly remap dumping methods



49
50
51
52
53
54
# File 'lib/sparkle_formation/provider/terraform.rb', line 49

def self.extended(klass)
  klass.instance_eval do
    alias :non_terraform_dump :dump
    alias :dump :terraform_dump
  end
end

.included(klass) ⇒ Object

Properly remap dumping methods



41
42
43
44
45
46
# File 'lib/sparkle_formation/provider/terraform.rb', line 41

def self.included(klass)
  klass.class_eval do
    alias_method :non_terraform_dump, :dump
    alias_method :dump, :terraform_dump
  end
end

Instance Method Details

#apply_deep_nesting(*args) {|stack, resource, s_name| ... } ⇒ SparkleFormation::SparkleStruct

Apply deeply nested stacks. This is the new nesting approach and does not bubble parameters up to the root stack. Parameters are isolated to the stack resource itself and output mapping is automatically applied.

Yield Parameters:

  • stack (SparkleFormation)

    stack instance

  • resource (AttributeStruct)

    the stack resource

  • s_name (String)

    stack resource name

Yield Returns:

  • (Hash)

    key/values to be merged into resource properties

Returns:



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/sparkle_formation/provider/terraform.rb', line 80

def apply_deep_nesting(*args, &block)
  outputs = collect_outputs
  nested_stacks(:with_resource).each do |stack, resource|
    unless stack.nested_stacks.empty?
      stack.apply_deep_nesting(*args)
    end
    stack.compile.parameters.keys!.each do |parameter_name|
      if output_name = output_matched?(parameter_name, outputs.keys)
        next if outputs[output_name] == stack
        stack_output = stack.make_output_available(output_name, outputs, self)
        # NOTE: Only set value if not already explicitly set
        if resource.properties.parameters._set(parameter_name).nil?
          resource.properties.parameters._set(parameter_name, stack_output)
        end
      end
    end
  end
  if block_given?
    extract_templates(&block)
  end
  self
end

#apply_shallow_nesting(*args, &block) ⇒ Object

Forcibly disable shallow nesting



104
105
106
# File 'lib/sparkle_formation/provider/terraform.rb', line 104

def apply_shallow_nesting(*args, &block)
  raise NotImplementedError.new "Shallow nesting is not supported for this provider!"
end

#generate_policyHash

Generate policy for stack

Returns:

  • (Hash)


66
67
68
# File 'lib/sparkle_formation/provider/terraform.rb', line 66

def generate_policy
  {}
end

#make_output_available(output_name, outputs, source_stack) ⇒ Hash

Extract output to make available for stack parameter usage at the current depth

Parameters:

  • output_name (String)

    name of output

  • outputs (Hash)

    listing of outputs

  • source_stack (SparkleFormation)

    requesting stack

Returns:

  • (Hash)

    reference to output value (used for setting parameter)



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/sparkle_formation/provider/terraform.rb', line 115

def make_output_available(output_name, outputs, source_stack)
  bubble_path = outputs[output_name].root_path - root_path
  drip_path = root_path - outputs[output_name].root_path
  bubble_path.each_slice(2) do |base_sparkle, ref_sparkle|
    next unless ref_sparkle
    base_sparkle.compile.outputs._set(output_name)._set(
      :value, base_sparkle.compile._stack_output(
        ref_sparkle.name, output_name
      )
    )
  end
  if bubble_path.empty?
    if drip_path.size == 1
      parent = drip_path.first.parent
      if parent && !parent.compile.parameters._set(output_name).nil?
        return compile.parameter!(output_name)
      end
    end
    raise ArgumentError.new "Failed to detect available bubbling path for output `#{output_name}`. " <<
                              "This may be due to a circular dependency! " <<
                              "(Output Path: #{outputs[output_name].root_path.map(&:name).join(" > ")} " <<
                              "Requester Path: #{root_path.map(&:name).join(" > ")})"
  end
  result = source_stack.compile._stack_output(bubble_path.first.name, output_name)
  if drip_path.size > 1
    parent = drip_path.first.parent
    drip_path.unshift(parent) if parent
    drip_path.each_slice(2) do |base_sparkle, ref_sparkle|
      next unless ref_sparkle
      base_sparkle.compile.resources[ref_sparkle.name].properties.parameters.value._set(output_name, result)
      ref_sparkle.compile.parameters._set(output_name).type "string" # TODO: <<<<------ type check and prop
      result = compile._parameter(output_name)
    end
  end
  result
end

#stack_resource_typeString

Note:

Nested templates aren't defined as a specific type thus no "real" type exists. So we'll create a custom one!

Returns Type string for terraform stack resource

Returns:

  • (String)

    Type string for terraform stack resource



59
60
61
# File 'lib/sparkle_formation/provider/terraform.rb', line 59

def stack_resource_type
  "module"
end

#terraform_dumpHash

Customized dump to break out templates into consumable structures for passing to the deployment manager API

Returns:

  • (Hash)


12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/sparkle_formation/provider/terraform.rb', line 12

def terraform_dump
  result = non_terraform_dump.to_smash
  Smash.new(
    :parameters => :variable,
    :resources => :resource,
    :outputs => :output,
  ).each do |original, updated|
    if val = result.delete(original)
      result[updated] = val
    end
  end
  if resources = result.delete(:resource)
    result[:resource] = Smash.new
    resources.each do |r_name, r_info|
      if !r_info[:type]
        r_type = r_name
        r_info.each do |r_name, r_props|
          r_info = Smash.new(type: r_type, properties: r_props)
          result.set(:resource, r_info[:type], r_name, r_info[:properties])
        end
      else
        result.set(:resource, r_info[:type], r_name, r_info[:properties])
      end
    end
  end
  result
end