Skip to content

Conversation

@Dav-14
Copy link
Contributor

@Dav-14 Dav-14 commented Oct 13, 2025

No description provided.

@Dav-14 Dav-14 requested a review from a team as a code owner October 13, 2025 16:08
@coderabbitai
Copy link

coderabbitai bot commented Oct 13, 2025

Walkthrough

Removes per-resource logger fields and logger injections, adds OpenTelemetry tracing utilities and a ResourceTracer wrapper, makes ledger bucket and metadata computed with defaults, updates e2e ledger tests and Terraform example env, adds Justfile terraform targets, and introduces a shared OTLP tracer.

Changes

Cohort / File(s) Summary
Env example
./.env.exemple
Adds TF_CLI_ARGS="-json" to the example environment file.
Ledger resource
internal/resources/ledger_ledger.go
Makes bucket and metadata attributes Computed: true and provides defaults (metadata via mapdefault.StaticValue); removes logger field and constructor logger param; Create now calls GetLedger and populates plan values from API response; drops logger context wiring.
Resource logging removal
internal/resources/noop.go, internal/resources/payments_connectors.go, internal/resources/payments_pool.go, internal/resources/reconciliation_policy.go, internal/resources/webhook_config.go
Removed logging import and logger fields; constructors no longer accept logger; lifecycle methods no longer inject per-operation logger context.
Resource tracing & wrapper
internal/resources/resource_tracer.go
New ResourceTracer type and NewResourceTracer constructor; wraps resources to add tracing, standardized Err... sentinel errors, injects trace context and logs around lifecycle method invocations.
Tracing helpers
pkg/tracing/tracing.go
Adds generic OpenTelemetry helpers: TraceTuple, Trace, and TraceError to start spans, run functions, and record errors/status.
OTLP tracer
internal/otlp/tracer.go
Adds shared exported Tracer variable via otel.Tracer("github.com/formancehq/terraform-provider-stack").
Provider resource wiring
internal/server/provider.go
Constructs base resource list without embedded loggers, then maps each resource through NewResourceTracer(p.logger, fn()) using collectionutils.Map; initializes provider logger with contextual field.
Justfile (terraform group targets)
Justfile
Adds init, apply, and destroy targets grouped under terraform to run terraform init -upgrade, terraform apply -auto-approve, and terraform destroy -auto-approve in examples.
E2E ledger tests
tests/e2e/ledger_test.go
Renames TestLedgerTestLedgerDefault, wraps tests in parallel harness, adds TestLedgerWithMetadata, removes explicit bucket from some configs, updates assertions to expect bucket _default, and adds a RefreshState step.
Integration test adjustment
tests/integration/noop_test.go
Comments out two test cases in TestNoop, reducing executed scenarios.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User (terraform)
  participant T as Terraform CLI
  participant P as Provider
  participant R as ResourceTracer
  participant S as Resource (e.g., Ledger)
  participant A as Backend API

  U->>T: terraform apply
  T->>P: call Resource Create
  P->>R: invoke traced resource
  R->>R: start span (TraceError)
  R->>S: call Create(ctx)
  S->>A: API Create (may omit bucket → backend sets to "_default")
  A-->>S: API Create response
  S->>S: (optional) GetLedger to fetch real fields
  S-->>R: return with diagnostics
  R->>R: end span, record error/status
  R-->>P: return to provider
  P-->>T: apply result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

I hopped through code with tiny paws,
Removed the logs, embraced new laws.
Traces hum softly, defaults set right,
Buckets named "_default" in morning light.
Thump-thump — a rabbit's quiet delight. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Title Check ⚠️ Warning The title “feat(ledger): defaulting bucket and metadata” only covers the ledger defaults but omits the extensive refactor of logging removal and the introduction of tracing infrastructure affecting multiple resources, so it does not fully summarize the primary scope of this pull request. Consider updating the title to reflect the overall scope, such as including the logging removal and tracing refactor, or splitting the ledger default bucket changes into a focused pull request.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description Check ❓ Inconclusive No pull request description was provided, which makes it impossible to verify if the description relates to any part of the changeset or provides meaningful context for reviewers. Please add a concise description summarizing the purpose and main changes of this pull request to help reviewers understand the intent and scope of the updates.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/ledger_default_bucket

Comment @coderabbitai help to get the list of available commands and usage tips.

@Dav-14 Dav-14 enabled auto-merge October 13, 2025 16:08
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
.env.exemple (1)

21-21: Consider minor style improvements.

Static analysis suggests a few optional refinements:

  • Remove quotes around -json (unnecessary for simple flags)
  • Add a blank line at the end of the file
  • Move TF_CLI_ARGS before TF_LOG for alphabetical ordering

These are stylistic preferences rather than functional issues.

-TF_CLI_ARGS="-json"
+
+TF_CLI_ARGS=-json
internal/resources/ledger_ledger.go (1)

133-135: Null check is now redundant but harmless.

With the default value set in the schema, plan.Bucket should never be null—it will contain either the user-specified value or "_default". The null check will always pass, making this condition unnecessary.

However, this doesn't cause any issues and can be considered defensive programming.

If you'd like to clean this up:

-	if !plan.Bucket.IsNull() {
-		config.V2CreateLedgerRequest.Bucket = pointer.For(plan.Bucket.ValueString())
-	}
+	config.V2CreateLedgerRequest.Bucket = pointer.For(plan.Bucket.ValueString())
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 0843be2 and 046dd47.

📒 Files selected for processing (3)
  • .env.exemple (1 hunks)
  • internal/resources/ledger_ledger.go (2 hunks)
  • tests/e2e/ledger_test.go (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/e2e/ledger_test.go (1)
tests/e2e/main_test.go (3)
  • CloudProvider (28-28)
  • StackProvider (29-29)
  • RegionName (30-30)
🪛 dotenv-linter (3.3.0)
.env.exemple

[warning] 21-21: [EndingBlankLine] No blank line at the end of the file

(EndingBlankLine)


[warning] 21-21: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 21-21: [UnorderedKey] The TF_CLI_ARGS key should go before the TF_LOG key

(UnorderedKey)

🔇 Additional comments (4)
internal/resources/ledger_ledger.go (2)

17-17: LGTM! Default bucket implementation looks correct.

The addition of Computed: true and Default: stringdefault.StaticString("_default") correctly implements the default bucket behavior. When users don't specify a bucket, it will automatically be set to "_default".

Also applies to: 58-60


58-60: Confirm _default is API’s expected default bucket
Ensure explicitly sending "_default" (instead of omitting the field) matches the API’s default bucket behavior.

tests/e2e/ledger_test.go (2)

15-69: LGTM! Tests correctly verify default bucket behavior.

The test restructuring and renaming to TestLedgerDefault appropriately reflects the new default bucket functionality. Key improvements:

  • Parallel test execution with proper provider factory setup
  • Terraform version checks
  • Multiple steps verify idempotency (same config applied twice)
  • RefreshState step ensures state refresh works correctly
  • Bucket expectations correctly set to "_default" when not explicitly specified

The test thoroughly validates that the default bucket value is applied and persisted correctly.


102-102: LGTM! Bucket expectations updated correctly.

The state checks now correctly expect bucket to be "_default" when not explicitly specified in the configuration, aligning with the schema changes in internal/resources/ledger_ledger.go.

Also applies to: 130-130

@Dav-14 Dav-14 force-pushed the fix/ledger_default_bucket branch 2 times, most recently from e9d374f to ca0f82e Compare October 13, 2025 16:18
@Dav-14 Dav-14 changed the title feat(ledger): defaulting bucket on _default feat(ledger): defaulting bucket and metadata Oct 13, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
.env.exemple (1)

21-21: Address linting issues.

The static analysis tool flagged minor formatting issues with this line:

  1. Missing blank line at the end of the file
  2. Quote characters in the value (the -json flag is wrapped in quotes)
  3. Key ordering (TF_CLI_ARGS should appear before TF_LOG for consistency)

Apply this diff to address the issues:

-TF_CLI_ARGS="-json"
+TF_CLI_ARGS=-json
+

And consider moving this line to appear before the TF_LOG declarations (lines 18-20) for better organization.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 046dd47 and ca0f82e.

📒 Files selected for processing (3)
  • .env.exemple (1 hunks)
  • internal/resources/ledger_ledger.go (3 hunks)
  • tests/e2e/ledger_test.go (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/e2e/ledger_test.go (1)
tests/e2e/main_test.go (3)
  • CloudProvider (28-28)
  • StackProvider (29-29)
  • RegionName (30-30)
🪛 dotenv-linter (3.3.0)
.env.exemple

[warning] 21-21: [EndingBlankLine] No blank line at the end of the file

(EndingBlankLine)


[warning] 21-21: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 21-21: [UnorderedKey] The TF_CLI_ARGS key should go before the TF_LOG key

(UnorderedKey)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Tests (E2E)
🔇 Additional comments (6)
internal/resources/ledger_ledger.go (4)

17-18: LGTM! Imports added for default value helpers.

The imports for mapdefault and stringdefault are correctly added to support the new default values for the bucket and metadata attributes.


57-62: LGTM! Bucket now defaults to "_default".

The bucket attribute is now Optional + Computed with a default value of "_default". This ensures users don't need to explicitly specify a bucket, and the resource will use "_default" when omitted.


68-74: LGTM! Metadata now defaults to an empty map.

The metadata attribute is now Optional + Computed with a default empty map. This provides a consistent default when metadata is not specified.


136-138: Note: Behavioral change in bucket handling.

With the bucket attribute now being Computed with a default value, plan.Bucket.IsNull() will always return false (it will contain either the user-provided value or the default "_default"). This means the bucket will now always be sent to the API, whereas previously it might have been omitted when not specified by the user.

Ensure this aligns with the API's expectations and doesn't cause any unexpected behavior.

tests/e2e/ledger_test.go (2)

15-68: LGTM! Test properly validates default bucket behavior.

The renamed TestLedgerDefault function now includes:

  • Proper parallel test setup with provider factories
  • Two sequential configurations that create a ledger without specifying a bucket
  • State checks that verify the bucket defaults to "_default"
  • A refresh state step to ensure stability

This thoroughly validates the new default bucket functionality.


71-145: LGTM! Metadata test updated for default bucket.

The TestLedgerWithMetadata function correctly validates:

  • Ledger creation with metadata but no explicit bucket specification
  • State checks confirming the bucket defaults to "_default" (lines 102, 130)
  • Metadata updates work correctly with the default bucket
  • RefreshState ensures consistency

@codecov
Copy link

codecov bot commented Oct 13, 2025

Codecov Report

❌ Patch coverage is 70.16575% with 54 lines in your changes missing coverage. Please review.
✅ Project coverage is 53.91%. Comparing base (0843be2) to head (3fa5218).

Files with missing lines Patch % Lines
internal/resources/resource_tracer.go 65.69% 40 Missing and 7 partials ⚠️
internal/resources/ledger_ledger.go 75.00% 3 Missing and 1 partial ⚠️
internal/resources/reconciliation_policy.go 50.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #31      +/-   ##
==========================================
- Coverage   56.94%   53.91%   -3.03%     
==========================================
  Files          19       20       +1     
  Lines        1454     1519      +65     
==========================================
- Hits          828      819       -9     
- Misses        519      583      +64     
- Partials      107      117      +10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Dav-14 Dav-14 force-pushed the fix/ledger_default_bucket branch from ca0f82e to 83c6f67 Compare October 16, 2025 13:49
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (7)
Justfile (1)

56-70: Consider consolidating [group('terraform')] declarations.

Each terraform target has its own [group('terraform')] declaration (lines 56, 60, 64, 68). While valid, Justfile supports grouping multiple recipes under a single group attribute for better readability:

-[group('terraform')]
-init examples="install-verif": build
-  @cd examples/{{examples}} && terraform init -upgrade
-
-[group('terraform')]
-plan examples="install-verif": build
-  @cd examples/{{examples}} && terraform plan -generate-config-out=generated.tf
-
-[group('terraform')]
-apply examples="install-verif": build
-  @cd examples/{{examples}} && terraform apply -auto-approve
-
-[group('terraform')]
-destroy examples="install-verif": build
-  @cd examples/{{examples}} && terraform destroy -auto-approve
+[group('terraform')]
+init examples="install-verif": build
+  @cd examples/{{examples}} && terraform init -upgrade
+
+plan examples="install-verif": build
+  @cd examples/{{examples}} && terraform plan -generate-config-out=generated.tf
+
+apply examples="install-verif": build
+  @cd examples/{{examples}} && terraform apply -auto-approve
+
+destroy examples="install-verif": build
+  @cd examples/{{examples}} && terraform destroy -auto-approve
pkg/tracing/tracing.go (3)

10-24: Variable shadowing and redundant declarations.

Lines 11, 16: The local variable trace shadows the imported trace package (line 7), which could cause confusion. Consider renaming it to span.

Lines 14-16: The zero-value declarations for k and v are redundant since line 16 reassigns them immediately.

Apply this diff to address both issues:

-func TraceTuple[K, V any](ctx context.Context, tracer trace.Tracer, name string, fn func(ctx context.Context) (K, V, error), opts ...trace.SpanStartOption) (K, V, error) {
-	ctx, trace := tracer.Start(ctx, name, opts...)
-	defer trace.End()
-
-	var k K
-	var v V
-	k, v, err := fn(ctx)
+func TraceTuple[K, V any](ctx context.Context, tracer trace.Tracer, name string, fn func(ctx context.Context) (K, V, error), opts ...trace.SpanStartOption) (K, V, error) {
+	ctx, span := tracer.Start(ctx, name, opts...)
+	defer span.End()
+
+	k, v, err := fn(ctx)
 	if err != nil {
-		trace.RecordError(err)
-		trace.SetStatus(codes.Error, err.Error())
+		span.RecordError(err)
+		span.SetStatus(codes.Error, err.Error())
 		return k, v, err
 	}
 
 	return k, v, nil
 }

26-39: Variable shadowing and unused zero value.

Line 27: The local variable trace shadows the imported trace package.

Line 30: zeroRet is only used in the error path, making its declaration on line 30 slightly redundant (though acceptable for clarity).

Apply this diff to rename the span variable:

 func Trace[RET any](ctx context.Context, tracer trace.Tracer, name string, fn func(ctx context.Context) (RET, error), opts ...trace.SpanStartOption) (RET, error) {
-	ctx, trace := tracer.Start(ctx, name, opts...)
-	defer trace.End()
+	ctx, span := tracer.Start(ctx, name, opts...)
+	defer span.End()
 
 	var zeroRet RET
 	ret, err := fn(ctx)
 	if err != nil {
-		trace.RecordError(err)
-		trace.SetStatus(codes.Error, err.Error())
+		span.RecordError(err)
+		span.SetStatus(codes.Error, err.Error())
 		return zeroRet, err
 	}
 
 	return ret, nil
 }

41-51: Variable shadowing.

Line 42: The local variable trace shadows the imported trace package.

Apply this diff:

 func TraceError(ctx context.Context, tracer trace.Tracer, name string, fn func(ctx context.Context) error, opts ...trace.SpanStartOption) error {
-	ctx, trace := tracer.Start(ctx, name, opts...)
-	defer trace.End()
+	ctx, span := tracer.Start(ctx, name, opts...)
+	defer span.End()
 
 	if err := fn(ctx); err != nil {
-		trace.RecordError(err)
-		trace.SetStatus(codes.Error, err.Error())
+		span.RecordError(err)
+		span.SetStatus(codes.Error, err.Error())
 		return err
 	}
 	return nil
 }
internal/resources/reconciliation_policy.go (1)

238-239: TODO: Remove resource from state if not found.

Lines 238-239 note a TODO to remove the resource from state if not found during Read, which would trigger recreation. This pattern should be applied consistently across all resources.

Do you want me to open a new issue to track this task across all resources, or would you like me to generate a script to identify all Read methods that need this pattern?

internal/resources/resource_tracer.go (2)

186-200: Missing debug logs in Schema operation.

Lines 192-193: Unlike other operations (ValidateConfig, ImportState, Configure, Create, Delete, Read, Update), the Schema wrapper does not include debug log statements for "called" and "completed" events. This inconsistency could make debugging harder.

Apply this diff to add debug logging:

 func (r *ResourceTracer) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
 	ctx = logging.ContextWithLogger(ctx, r.logger)
 	operation := "Schema"
 	if v, ok := r.underlyingValue.(resource.Resource); ok {
 		_ = tracing.TraceError(ctx, otlp.Tracer, operation, func(ctx context.Context) error {
 			ctx = injectTraceContext(ctx, v, operation)
+			logging.FromContext(ctx).Debug(operation + " called")
+			defer logging.FromContext(ctx).Debug(operation + " completed")
 			v.Schema(ctx, req, resp)
 			if resp.Diagnostics.HasError() {
 				return ErrSchema
 			}
 			return nil
 		})
 	}
 }

202-216: Missing debug logs in Update operation.

Lines 208-209: The Update wrapper does not include debug log statements for "called" and "completed" events, unlike other operations. This inconsistency could make debugging harder.

Apply this diff to add debug logging:

 func (r *ResourceTracer) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
 	ctx = logging.ContextWithLogger(ctx, r.logger)
 	operation := "Update"
 	if v, ok := r.underlyingValue.(resource.Resource); ok {
 		_ = tracing.TraceError(ctx, otlp.Tracer, operation, func(ctx context.Context) error {
 			ctx = injectTraceContext(ctx, v, operation)
+			logging.FromContext(ctx).Debug(operation + " called")
+			defer logging.FromContext(ctx).Debug(operation + " completed")
 			v.Update(ctx, req, resp)
 			if resp.Diagnostics.HasError() {
 				return ErrUpdate
 			}
 			return nil
 		})
 	}
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ca0f82e and 83c6f67.

📒 Files selected for processing (14)
  • .env.exemple (1 hunks)
  • Justfile (1 hunks)
  • internal/otlp/tracer.go (1 hunks)
  • internal/resources/ledger_ledger.go (6 hunks)
  • internal/resources/noop.go (1 hunks)
  • internal/resources/payments_connectors.go (2 hunks)
  • internal/resources/payments_pool.go (2 hunks)
  • internal/resources/reconciliation_policy.go (7 hunks)
  • internal/resources/resource_tracer.go (1 hunks)
  • internal/resources/webhook_config.go (2 hunks)
  • internal/server/provider.go (3 hunks)
  • pkg/tracing/tracing.go (1 hunks)
  • tests/e2e/ledger_test.go (3 hunks)
  • tests/integration/noop_test.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (9)
internal/server/provider.go (7)
internal/resources/webhook_config.go (1)
  • NewWebhooks (37-41)
internal/resources/ledger_ledger.go (1)
  • NewLedger (39-43)
internal/resources/noop.go (1)
  • NewNoop (24-28)
internal/resources/payments_connectors.go (1)
  • NewPaymentsConnectors (119-123)
internal/resources/payments_pool.go (1)
  • NewPaymentsPool (33-37)
internal/resources/reconciliation_policy.go (1)
  • NewReconciliationPolicy (69-73)
internal/resources/resource_tracer.go (1)
  • NewResourceTracer (23-31)
internal/resources/ledger_ledger.go (2)
internal/stores.go (1)
  • ModuleStore (32-38)
internal/server/sdk/errors.go (1)
  • HandleStackError (13-59)
internal/resources/payments_pool.go (1)
internal/stores.go (1)
  • ModuleStore (32-38)
tests/e2e/ledger_test.go (1)
tests/e2e/main_test.go (3)
  • CloudProvider (28-28)
  • StackProvider (29-29)
  • RegionName (30-30)
internal/resources/reconciliation_policy.go (1)
internal/stores.go (1)
  • ModuleStore (32-38)
pkg/tracing/tracing.go (1)
internal/otlp/tracer.go (1)
  • Tracer (7-7)
internal/resources/resource_tracer.go (2)
pkg/tracing/tracing.go (1)
  • TraceError (41-51)
internal/otlp/tracer.go (1)
  • Tracer (7-7)
internal/resources/payments_connectors.go (1)
internal/stores.go (1)
  • ModuleStore (32-38)
internal/resources/webhook_config.go (1)
internal/stores.go (1)
  • ModuleStore (32-38)
🪛 dotenv-linter (3.3.0)
.env.exemple

[warning] 21-21: [EndingBlankLine] No blank line at the end of the file

(EndingBlankLine)


[warning] 21-21: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 21-21: [UnorderedKey] The TF_CLI_ARGS key should go before the TF_LOG key

(UnorderedKey)

🔇 Additional comments (20)
Justfile (1)

56-58: LGTM! New init target follows existing conventions.

The addition of the init target is well-implemented and consistent with the existing terraform targets. It correctly depends on the build target, uses the same default example value, and employs the -upgrade flag which is appropriate for development workflows.

tests/integration/noop_test.go (1)

47-61: Verify intentional reduction in test coverage.

Two test cases have been commented out: one for invalid client_id and one for missing client_secret. This reduces validation coverage.

Were these scenarios intentionally removed? If so, please document why these validation paths are no longer required. If not, consider restoring them or relocating to a more appropriate test suite.

internal/resources/noop.go (1)

24-27: LGTM!

The constructor signature has been simplified to remove the logger dependency, aligning with the broader architectural shift to use a tracing wrapper at the provider level instead of per-resource loggers.

tests/e2e/ledger_test.go (2)

15-69: LGTM!

The new TestLedgerDefault test properly validates the default bucket behavior. The test creates a ledger without specifying a bucket and verifies that it defaults to "_default", which aligns with the resource changes making bucket computed with a default value.


102-102: LGTM!

The test assertions have been correctly updated to expect bucket="_default" instead of custom bucket values, which aligns with the new computed default behavior of the ledger resource.

Also applies to: 130-130

internal/resources/payments_pool.go (1)

23-36: LGTM!

The removal of the logger field and simplification of the constructor align with the architectural shift to use provider-level tracing wrappers instead of per-resource loggers.

internal/resources/webhook_config.go (1)

26-40: LGTM!

The removal of logger dependencies is consistent with the architectural changes across all resources in this PR.

internal/resources/ledger_ledger.go (3)

27-42: LGTM!

The removal of the logger field and simplification of the constructor are consistent with the architectural changes across all resources.


52-65: LGTM!

Making bucket computed and providing a default empty map for metadata improves the user experience by allowing these fields to be optional while still tracking their actual values from the API.


157-173: Approve change: fetch ledger state with GetLedger
Confirm API returns expected defaults when inputs are omitted:

  • Omitted bucket yields the server default bucket (e.g. _default)
  • Omitted metadata yields an empty map
internal/server/provider.go (2)

319-329: LGTM!

The resources are now wrapped with ResourceTracer to provide tracing capabilities at the provider level. This replaces the previous approach of passing loggers to individual resource constructors, centralizing observability concerns.


473-473: LGTM!

Adding the "provider": "stack" contextual field to the logger improves observability by making it clear which provider is generating log entries.

internal/otlp/tracer.go (1)

1-7: LGTM!

The shared tracer instance provides a centralized OpenTelemetry tracer for the provider. The tracer name "github.com/formancehq/terraform-provider-stack" follows the convention of using the full package path.

internal/resources/payments_connectors.go (1)

48-50: LGTM! Logger removal aligns with tracer-based observability.

The removal of the logger field and the updated constructor signature are consistent with the broader refactoring where resources no longer manage their own loggers. Instead, the ResourceTracer wrapper (introduced in internal/resources/resource_tracer.go) injects logging context at runtime.

Also applies to: 119-123

internal/resources/reconciliation_policy.go (4)

28-30: LGTM! Logger removal aligns with tracer-based observability.

The removal of the logger field and the updated constructor are consistent with the broader refactoring where ResourceTracer injects logging context at runtime.

Also applies to: 69-73


85-87: LGTM! PlanModifiers correctly enforce replacement.

The RequiresReplace() plan modifiers on ledger_name, name, payments_pool_id, and ledger_query appropriately mark these fields as immutable, triggering resource replacement when they change.

Also applies to: 92-94, 99-101, 106-108


261-261: LGTM! Appropriate warning for unimplemented Update.

The warning clearly communicates that the Update method is not implemented and the resource will be recreated. This is appropriate given the RequiresReplace() plan modifiers on all configurable fields.


152-152: Logger injection verified in ResourceTracer.ValidateConfig
logging.ContextWithLogger(ctx, r.logger) is invoked before calling v.ValidateConfig, so no changes are necessary.

internal/resources/resource_tracer.go (2)

23-61: LGTM! Solid foundation for resource tracing.

The constructor, struct, sentinel errors, and injectTraceContext helper establish a clean pattern for wrapping resources with tracing and logging. The use of OpenTelemetry propagation and contextual logging enrichment is appropriate.


64-79: LGTM! Consistent tracing wrapper pattern.

The wrapper methods for ValidateConfig, ImportState, Configure, Create, Delete, and Read follow a consistent pattern:

  1. Inject logger into context
  2. Check if underlying resource implements the interface
  3. Wrap execution with tracing
  4. Inject trace context
  5. Log entry/exit
  6. Call underlying method
  7. Return sentinel error if diagnostics has errors

This provides excellent observability while keeping resources decoupled from logging concerns.

Also applies to: 81-97, 99-115, 117-133, 135-151, 168-184

TF_LOG=TRACE
TF_LOG_FORMAT=JSON
TF_LOG_PATH=./terraform.log
TF_CLI_ARGS="-json"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Don’t set TF_CLI_ARGS to -json globally

TF_CLI_ARGS is prepended to every Terraform command. Most commands (terraform init, apply, etc.) reject -json, so sourcing this example will make the CLI fail with “flag provided but not defined: -json”. Use the command-scoped env vars instead (e.g., TF_CLI_ARGS_plan=-json) or drop this line.

-TF_CLI_ARGS="-json"
+# Example: enable JSON output only for plan
+# TF_CLI_ARGS_plan="-json"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
TF_CLI_ARGS="-json"
# Example: enable JSON output only for plan
# TF_CLI_ARGS_plan="-json"
🧰 Tools
🪛 dotenv-linter (3.3.0)

[warning] 21-21: [EndingBlankLine] No blank line at the end of the file

(EndingBlankLine)


[warning] 21-21: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 21-21: [UnorderedKey] The TF_CLI_ARGS key should go before the TF_LOG key

(UnorderedKey)

🤖 Prompt for AI Agents
In .env.exemple around line 21, TF_CLI_ARGS is set globally to "-json", which
breaks most terraform commands; remove or comment out this global assignment and
either delete the line or replace it with command-scoped variables such as
TF_CLI_ARGS_plan=-json (or TF_CLI_ARGS_apply=-json) so only the intended
terraform subcommands receive the -json flag.

@Dav-14 Dav-14 closed this Oct 17, 2025
auto-merge was automatically disabled October 17, 2025 11:43

Pull request was closed

@Dav-14 Dav-14 deleted the fix/ledger_default_bucket branch October 17, 2025 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants