module Terraformer class TerraformFileNotFound < RuntimeError end class TerraformInvalidTfstateFile < RuntimeError end class Terraform class << self def execute(data, klass_name, options) tf(data[:tf], klass_name, options[:name]) tfstate(data[:tfstate], options[:merge]) end def tf(generated_tf, klass_name, tf_path) tf_file_name = "#{klass_name.split('::')[-1].downcase}.tf" tf_file_name = tf_path unless tf_path.nil? if File.file?(tf_file_name) UserInput.ask("File: #{tf_file_name} already exists. Overwrite?", "Y", "n") end File.open(tf_file_name, "w") do |f| f.write(generated_tf) end end def tfstate(generated_tfstate, tfstate_path) unless tfstate_path.nil? if File.file?(tfstate_path) tfstate = parse_json_file(tfstate_path) else raise TerraformFileNotFound, "File not found while trying to merge state file with: #{tfstate_path}." end else tfstate_path = "terraform.tfstate" if File.file?(tfstate_path) UserInput.ask("File: #{tfstate_path} already exists and the 'merge' option was not passed. Overwrite?", "Y", "n") end tfstate = tfstate_skeleton end tfstate["serial"] = tfstate["serial"] + 1 tfstate["modules"][0]["resources"] = tfstate["modules"][0]["resources"].merge(generated_tfstate) state_file = JSON.pretty_generate(tfstate) File.open(tfstate_path, "w+") do |f| f.write(state_file) f.flush end end def parse_json_file(file_path) file_content = File.read(file_path) JSON.parse(file_content) rescue JSON::ParserError raise TerraformInvalidTfstateFile, "Unable to parse: #{file_path}." end def tfstate_skeleton { "version" => 3, "terraform_version" => "0.7.3", "serial" => 0, "lineage" => SecureRandom.uuid, "modules" => [ { "path" => [ "root" ], "outputs" => {}, "resources" => {}, "depends_on" => [] } ] } end end end end