Example on how to load helper from within app.rb?

Guys, can someone please give me an example on how to access helper methods from within app.rb? Specifically built in helper of AWS secrets manager.

Currently stuck on:

# Docs: https://terraspace.cloud/docs/config/reference/
Terraspace.configure do |config|
  config.allow.envs = [
    "dev",
    "devops",
    "qa",
    "prep",
    "prod"
  ]
  config.build.cache_dir = ":CACHE_ROOT/:ENV/:BUILD_DIR"
  config.init.mode = :always
  # config.logger.level = :info
  config.summary.prune = true
end

class SecretsLoader
  include TerraspacePluginAws::Interfaces::Helper

  def initialize()
    puts aws_secret("secret name")
  end
end

SecretsLoader.new()

However I get:

/opt/terraspace/embedded/lib/ruby/gems/3.0.0/gems/dsl_evaluator-0.3.0/lib/dsl_evaluator/printer.rb:49:in `info_from_backtrace': undefined method `first' for nil:NilClass (NoMethodError)
        from /opt/terraspace/embedded/lib/ruby/gems/3.0.0/gems/dsl_evaluator-0.3.0/lib/dsl_evaluator/printer.rb:23:in `error_info'
        from /opt/terraspace/embedded/lib/ruby/gems/3.0.0/gems/dsl_evaluator-0.3.0/lib/dsl_evaluator/printer.rb:9:in `print'
        from /opt/terraspace/embedded/lib/ruby/gems/3.0.0/gems/dsl_evaluator-0.3.0/lib/dsl_evaluator.rb:22:in `rescue in evaluate_file'
        from /opt/terraspace/embedded/lib/ruby/gems/3.0.0/gems/dsl_evaluator-0.3.0/lib/dsl_evaluator.rb:18:in `evaluate_file'
        from /opt/terraspace/embedded/lib/ruby/gems/3.0.0/gems/terraspace-1.1.7/lib/terraspace/app.rb:89:in `load_project_config'
        from /opt/terraspace/embedded/lib/ruby/gems/3.0.0/gems/terraspace-1.1.7/lib/terraspace/core.rb:37:in `config'
        from /opt/terraspace/embedded/lib/ruby/gems/3.0.0/gems/memoist-0.16.2/lib/memoist.rb:169:in `config'
        from /opt/terraspace/embedded/lib/ruby/gems/3.0.0/gems/terraspace-1.1.7/lib/terraspace/booter.rb:20:in `set_plugin_cache!'
        from /opt/terraspace/embedded/lib/ruby/gems/3.0.0/gems/terraspace-1.1.7/lib/terraspace/booter.rb:9:in `boot'
        from /opt/terraspace/embedded/lib/ruby/gems/3.0.0/gems/terraspace-1.1.7/lib/terraspace.rb:38:in `<top (required)>'
        from <internal:/opt/terraspace/embedded/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
        from <internal:/opt/terraspace/embedded/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
        from /opt/terraspace/embedded/lib/ruby/gems/3.0.0/gems/terraspace-1.1.7/exe/terraspace:11:in `<top (required)>'
        from /usr/local/bin/terraspace:25:in `load'
        from /usr/local/bin/terraspace:25:in `<main>'
/home/xxx/Documents/Projects/xxx/config/app.rb:20:in `initialize': undefined method `resolved' for nil:NilClass (NoMethodError)
        from /home/xxx/Documents/Projects/xxx/config/app.rb:24:in `new'
        from /home/xxx/Documents/Projects/xxx/config/app.rb:24:in `evaluate_file'
        from /opt/terraspace/embedded/lib/ruby/gems/3.0.0/gems/dsl_evaluator-0.3.0/lib/dsl_evaluator.rb:20:in `instance_eval'
        from /opt/terraspace/embedded/lib/ruby/gems/3.0.0/gems/dsl_evaluator-0.3.0/lib/dsl_evaluator.rb:20:in `evaluate_file'
        from /opt/terraspace/embedded/lib/ruby/gems/3.0.0/gems/memoist-0.16.2/lib/memoist.rb:169:in `config'
        from <internal:/opt/terraspace/embedded/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
        from <internal:/opt/terraspace/embedded/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
        from /opt/terraspace/embedded/lib/ruby/gems/3.0.0/gems/terraspace-1.1.7/exe/terraspace:11:in `<top (required)>'
        from /usr/local/bin/terraspace:25:in `load'
        from /usr/local/bin/terraspace:25:in `<main>'

So, in general, since you’re trying to add methods to self within config/app.rb, the extend keyword can be used. It would be something like this:

config/app.rb

self.send(:extend, TerraspacePluginAws::Interfaces::Helper)

However, don’t recommend it as it won’t work with the way Terraspace currently implements helpers. This is because terraspace helpers are used as part of terraspace all dependency graph calculation, and terraspace processes some files twice. Hence the helper methods are called twice. 1st pass: to calculate the dependency graph. 2nd pass: With the resolved graph, the output values are fetched from terraform state pull.

This is mentioned here:

So if you try to call aws_secret, you’ll see an error undefined method resolved' for nil:NilClass for !!@mod.resolved. It’s because when calling the helper methods directly it’s always the first pass. Don’t think there’s no way to force into the 2nd pass without even more hackery. Also, in the config/app.rb the @mod instance variable is unavailable.

Think will change the way double-processing works, only evaluating the helper methods required for dependency graph calculations on the first pass. This solves the issue more generally. This would make it possible to call methods like aws_secrets without dealing with the double-pass.

As part of this, would probably also add helpers support to config/app.rb automatically, so then you don’t even have use extend hackery. Have recently been adding the helper support concept to the config file in other tools like VPC Settings - UFO ECS Deploy Tool and can see its usefulness. Unsure when will get to this, though. :clock130: Will review and consider PRs for this. Of course, no sweat either way. :+1: