Module: TFW

Defined in:
lib/tfw.rb,
lib/tfw/state.rb,
lib/tfw/module.rb,
lib/tfw/setters.rb,
lib/tfw/version.rb,
lib/tfw/stack_methods.rb,
lib/tfw/aws_sg_workaround.rb

Overview

TFW is a Terraform Wrapper which uses terraform DSL for Ruby

Defined Under Namespace

Modules: AwsSgWorkaround, CreateStackMethods, Setters Classes: Module, StackMethods, State

Constant Summary collapse

LIB_DIR =
"#{__dir__}/tfw/"
WORKSPACE =
'./.tfw'
VERSION =
'0.1.19'

Class Method Summary collapse

Class Method Details

.as_json?Boolean

Returns:

  • (Boolean)


24
25
26
# File 'lib/tfw.rb', line 24

def as_json?
  !ENV['TFW_AS_JSON'].nil?
end

.build_configObject



44
45
46
47
48
49
# File 'lib/tfw.rb', line 44

def build_config
  FileUtils.mkdir_p WORKSPACE
  stack = TFW.get_stack_for_dir '.'
  stack_file = "#{WORKSPACE}/stack.tf"
  write_stack_file stack_file, stack
end

.cli(args) ⇒ Object



38
39
40
41
42
# File 'lib/tfw.rb', line 38

def cli(args)
  build_config
  State.instance.reset
  run_terraform args
end

.configure_input_method(input) ⇒ Object



115
116
117
118
119
120
# File 'lib/tfw.rb', line 115

def configure_input_method(input)
  silent_block do
    # This will trigger warnings as we are redefining methods
    TOPLEVEL_BINDING.eval('self').define_singleton_method('tfw_module_input') { input }
  end
end

.configure_methods_using_stack(stack) ⇒ Object



104
105
106
107
108
109
110
111
112
113
# File 'lib/tfw.rb', line 104

def configure_methods_using_stack(stack)
  silent_block do
    # This will trigger warnings as we are redefining methods
    %w[provider variable locals tfmodule datasource resource output terraform].each do |name|
      TOPLEVEL_BINDING.eval('self').define_singleton_method name do |*args, &block|
        stack.method(name).call(*args, &block)
      end
    end
  end
end

.get_stack_for_dir(dir, input = nil, stack = State.instance.stack) ⇒ Object



28
29
30
31
32
33
34
35
36
# File 'lib/tfw.rb', line 28

def get_stack_for_dir(dir, input = nil, stack = State.instance.stack)
  configure_methods_using_stack stack
  configure_input_method input

  files = Dir.glob "#{dir}/*.rb"
  files.sort.each { |f| load f }
  configure_methods_using_stack State.instance.stack
  stack
end

.load_module(stack, &block) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/tfw.rb', line 74

def load_module(stack, &block)
  t = TFW::Module.new do
    instance_eval(&block) if block_given?
  end

  mstack = t.instance_variable_get '@stack'
  mname = t.instance_variable_get '@name'
  mpath = "./modules/#{mname}"

  FileUtils.mkdir_p "#{WORKSPACE}/#{mpath}"

  stack_file = "#{WORKSPACE}/#{mpath}/stack.tf"
  write_stack_file stack_file, mstack

  stack.tfmodule mname do
    source mpath
  end
end

.pretty_json(json) ⇒ Object



122
123
124
# File 'lib/tfw.rb', line 122

def pretty_json(json)
  JSON.pretty_generate JSON.parse(json)
end

.run_terraform(args) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/tfw.rb', line 51

def run_terraform(args)
  old_dir = Dir.pwd
  Dir.chdir WORKSPACE

  cmd = "terraform #{args.join ' '}"
  pid = fork { exec cmd }
  Dir.chdir old_dir
  trap_pids [pid]
  Process.wait pid
  $?.exitstatus
end

.trap_pids(pids) ⇒ Object



63
64
65
66
67
68
69
70
71
72
# File 'lib/tfw.rb', line 63

def trap_pids(pids)
  %w[SIGINT SIGTERM].each do |sig|
    Signal.trap sig do
      pids.each { |pid| Process.kill sig, pid }
      Process.waitall
      puts "ERROR: TFW received and forwarded #{sig} to terraform"
      exit 2
    end
  end
end

.write_stack_file(stack_file, stack) ⇒ Object



93
94
95
96
97
98
99
100
101
102
# File 'lib/tfw.rb', line 93

def write_stack_file(stack_file, stack)
  [stack_file, "#{stack_file}.json"].each { |f| FileUtils.rm_f f }

  if as_json?
    stack_file = "#{stack_file}.json"
    File.write stack_file, pretty_json(AwsSgWorkaround.fix(stack.to_json))
  else
    File.write stack_file, stack
  end
end