Module: Pangea::RemoteState

Defined in:
lib/pangea/remote_state.rb

Overview

Cross-template state references — reads outputs directly from S3 state.

No Terraform data sources needed. At synthesis time, reads the other template’s .tfstate from S3, extracts the output value, and returns it as a literal string. This makes cross-template wiring simple and dependency-free.

Usage in a template:

vpc_id = Pangea::RemoteState.from_template(ws,
  template: 'akeyless-dev-cluster',
  output: :vpc_id,
)
# => "vpc-06b5744a5287e2d47" (actual VPC ID from state)

Or with explicit config:

vpc_id = Pangea::RemoteState.output(
  template: 'akeyless-dev-cluster',
  output: :vpc_id,
  bucket: 'pangea-terraform-state-376129857990',
  region: 'us-east-1',
)

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.dependenciesObject (readonly)

Returns the value of attribute dependencies.



33
34
35
# File 'lib/pangea/remote_state.rb', line 33

def dependencies
  @dependencies
end

Class Method Details

.configure(bucket:, region: 'us-east-1') ⇒ Object

Configure root state backend defaults (called once at boot). Templates inherit these — no need to pass bucket/region everywhere.

Parameters:

  • bucket (String)

    S3 bucket name

  • region (String) (defaults to: 'us-east-1')

    AWS region



78
79
80
81
# File 'lib/pangea/remote_state.rb', line 78

def configure(bucket:, region: 'us-east-1')
  @root_bucket = bucket
  @root_region = region
end

.dependency_graphHash

Get all templates this workspace depends on.

Returns:

  • (Hash)

    Map of template_name => [output_names_read]



103
104
105
# File 'lib/pangea/remote_state.rb', line 103

def dependency_graph
  @dependencies.dup
end

.from(template, output) ⇒ String?

Simple one-liner: read an output from another template. Requires configure() to have been called first (or pass bucket/region).

Usage:

Pangea::RemoteState.from('akeyless-dev-cluster', :vpc_id)

Parameters:

  • template (String)

    Source template name

  • output (Symbol, String)

    Output name to read

Returns:

  • (String, nil)

    The output value



69
70
71
# File 'lib/pangea/remote_state.rb', line 69

def from(template, output)
  self.output(template: template, output: output)
end

.from_template(ws, template:, output:) ⇒ String?

Read an output using WorkspaceConfig for backend details. Extracts bucket/region from the root pangea.yml state.s3 config.

Parameters:

  • ws (Object)

    Workspace config (any object with state/s3/bucket)

  • template (String)

    Source template name

  • output (Symbol, String)

    Output name to read

Returns:

  • (String, nil)

    The output value, or nil if not found

Raises:

  • (ArgumentError)


90
91
92
93
94
95
96
97
98
# File 'lib/pangea/remote_state.rb', line 90

def from_template(ws, template:, output:)
  # Try to extract bucket from workspace config hierarchy
  bucket = extract_bucket(ws)
  region = extract_region(ws)

  raise ArgumentError, "Cannot determine state bucket from workspace config" unless bucket

  self.output(template: template, output: output, bucket: bucket, region: region)
end

.output(template:, output:, bucket: nil, region: nil, state_key: nil) ⇒ String?

Read an output directly from another template’s S3 state file.

Parameters:

  • template (String)

    Source template name (state key prefix)

  • output (Symbol, String)

    Output name to read

  • bucket (String) (defaults to: nil)

    S3 bucket name (optional if root_config set)

  • region (String) (defaults to: nil)

    AWS region (optional if root_config set)

  • state_key (String) (defaults to: nil)

    Override state key (default: pangea convention)

Returns:

  • (String, nil)

    The output value, or nil if not found

Raises:

  • (ArgumentError)


43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/pangea/remote_state.rb', line 43

def output(template:, output:, bucket: nil, region: nil, state_key: nil)
  bucket ||= @root_bucket
  region ||= @root_region || 'us-east-1'

  raise ArgumentError, "No bucket configured. Call RemoteState.configure or pass bucket:" unless bucket

  # Pangea convention: pangea/{workspace}/{template}/terraform.tfstate
  key = state_key || "pangea/#{template}/#{template.tr('-', '_')}/terraform.tfstate"
  state = fetch_state(bucket: bucket, key: key, region: region)
  return nil unless state

  # Track dependency
  @dependencies[template] ||= []

  extract_output(state, output.to_s)
end

.reset!Object

Reset (for testing).



108
109
110
111
112
# File 'lib/pangea/remote_state.rb', line 108

def reset!
  @dependencies = {}
  @root_bucket = nil
  @root_region = nil
end