TerraCurl Terraform Provider

repository·main·Indexed 41 days ago

https://github.com/devops-rob/terraform-provider-terracurl

An open-source Terraform provider for declarative, configurable HTTP API interactions. It allows managing third-party APIs and internal services as Terraform resources using the terracurl_request resource, data source, ephemeral resource, and Actions (for Terraform 1.14+). Features include support for multipart form requests, HTTP Digest authentication, and a default_headers configuration to handle short-lived authentication tokens.

Tokens
20.6K
Snippets
41
Records
57
Agent score
49%

What's inside TerraCurl

  1. Digest Authentication vs. Default Headers

    main

    Choosing between Digest authentication and static headers depends on the authentication mechanism required by the API:

    FeatureUse digest_auth / default_digest_authUse default_headers
    MechanismChallenge-response (Digest)Static or Bearer-style
    Header HandlingHandled automatically by the transport layerYou must provide the exact Authorization string
    Best Use CaseAPIs requiring WWW-Authenticate: DigestAPIs using Authorization: Bearer <token> or Authorization: Basic <base64>
  2. Use Destroy Response Templating

    main

    TerraCurl allows you to use {response.<path>} placeholders in destroy_url, destroy_request_body, or destroy headers/query parameters. These placeholders resolve using data from the original create response. This is useful for APIs where the delete endpoint requires an ID or UUID generated by the server during creation.

    # Example: Using a path from a nested JSON response
    resource "terracurl_request" "nested_object" {
      name           = "nested-object"
      url            = "https://api.example.com/objects"
      method         = "POST"
      request_body   = jsonencode({ name = "example" })
      response_codes = [201]
      skip_read      = true
      skip_destroy   = false
    
      destroy_url            = "https://api.example.com/objects/{response.data.object_id}"
      destroy_method         = "DELETE"
      destroy_response_codes = [200]
    }
    
    # Example: Using a template in a POST body for destruction
    resource "terracurl_request" "body_destroy" {
      name           = "body-destroy"
      url            = "https://api.example.com/users"
      method         = "POST"
      request_body   = jsonencode({ name = "john" })
      response_codes = [201]
      skip_read      = true
      skip_destroy   = false
    
      destroy_url            = "https://api.example.com/deactivate"
      destroy_method         = "POST"
      destroy_request_body   = jsonencode({ user_id = "{response.data.user.uuid}" })
      destroy_response_codes = [200]
    }
  3. Proxy configuration precedence and authentication

    main

    Precedence Order

    1. Environment variable values are loaded first.
    2. Explicitly set provider attributes in the Terraform configuration override environment variables.
    3. no_proxy matching is applied last to determine if a host bypasses the proxy.

    Authenticated Proxies

    Proxy URLs can include credentials for authentication. TerraCurl uses Go's standard library proxy support.

    Limitations:

    • NTLM, Kerberos, and other enterprise authentication mechanisms are not supported.
    • SOCKS proxies are not supported.
    • Proxy settings affect outbound requests from the machine running Terraform, not the remote APIs themselves.
    provider "terracurl" {
      https_proxy = "http://user:password@proxy.example.com:8080"
    }
  4. Use Destroy Response Templating to inject create-time values

    main

    When a REST API returns a server-generated identifier (like an ID) during a POST request, you often need that same ID to perform a DELETE request. Because Terraform cannot reference a resource's own computed response attribute inside the same resource block, TerraCurl provides Destroy Response Templating.

    TerraCurl resolves {response.<path>} placeholders in destroy configuration fields by reading the stored create response JSON from the Terraform state at destroy time. This allows you to dynamically construct delete URLs, request bodies, or headers based on the data returned when the resource was first created.

    resource "terracurl_request" "example" {
      # ... create configuration ...
    
      # The placeholder will be replaced by the value from the create response
      destroy_url = "https://api.example.com/objects/{response.id}"
      destroy_method = "DELETE"
    }
  5. Compare write-only attributes with other secret handling options

    main

    When deciding how to handle sensitive data in TerraCurl, consider the following comparison:

    ApproachIn state?In plan?Destroy refresh
    headers / request_bodyYes (sensitive still stored)Hidden if sensitiveFrom state (can go stale)
    headers_wo / request_body_woNoNoFrom private snapshot
    Provider default_headersNo (provider config)NoRe-evaluated every run

    Note: For rotating destroy credentials without storing them in resource state, consider using the provider-level default_headers instead.

  6. Manage Digest Authentication state and destruction

    main

    When using Digest authentication, be aware of how credentials are stored and re-evaluated:

    • Provider Defaults vs. State: The provider-level default_digest_auth is not stored in the Terraform resource state; it is re-evaluated on every run (including destroy). This makes it the preferred method for credentials that might change between the apply and destroy phases.
    • Resource-level Credentials: Credentials defined within a resource block (e.g., digest_auth) are stored in the Terraform state (marked as sensitive). If you use destroy_digest_auth, those specific values are persisted in the state and can become stale if the credentials change.
    • Security Note: Because resource-level Digest credentials are stored in state, use provider-level default_digest_auth or default_headers if you must ensure credentials do not appear in the state file.
  7. Handle sensitive API responses in terracurl_request

    main

    By default, the response attribute contains the JSON response from the API. If the response contains secrets, set response_sensitive = true.

    When response_sensitive is enabled:

    1. The standard response attribute will be empty.
    2. The JSON response will be populated in the sensitive_response attribute (or sensitive_renew_response / sensitive_close_response for those phases).
    3. These sensitive attributes are marked as sensitive in Terraform and will not be displayed in plan output.
  8. Use the terracurl_request ephemeral resource

    main

    The terracurl_request ephemeral resource allows you to manage the lifecycle of an API session through three distinct phases: an initial request, an optional periodic renew, and an optional close request to clean up resources.

    This resource is designed for managing ephemeral state on a target platform. By default, skip_renew and skip_close are set to true. You must explicitly set them to false to enable the renewal and cleanup phases.

    Lifecycle Phases

    1. Request: The initial API call made when the resource is created.
    2. Renew (Optional): A recurring API call made at a specified renew_interval to keep the resource alive.
    3. Close (Optional): A final API call made when the resource is destroyed to clean up the target platform.
  9. Understand default_headers merge behavior and scope

    main

    Merge Behavior

    TerraCurl applies headers using a specific precedence order. In the event of a key collision, the provider-level header takes precedence:

    1. Resource-level headers (headers, read_headers, destroy_headers, etc.)
    2. Provider default_headers (Overrides resource headers with the same key)

    Note on Host header: The Host header (case-insensitive) overrides the HTTP Host header sent on the wire, regardless of the URL hostname.

    Scope

    The default_headers configuration applies to all outbound TerraCurl requests, including:

    • terracurl_request resources (create, read, destroy)
    • terracurl_request data sources
    • terracurl_request actions
    • terracurl_request ephemeral resources (open, renew, close)

    Limitations

    • Sensitivity: default_headers is marked as sensitive in the provider schema and will not appear in your Terraform plan output.
    • State Persistence: If you only set tokens in resource-level headers or destroy_headers, they remain persisted in the state and are subject to expiration. To ensure fresh tokens during destroy, they must be moved to default_headers or you must use write-only resource headers.
  10. How drift detection works for terracurl_request

    main

    The terracurl_request resource supports drift detection by comparing a stored response with a live response during the Terraform plan phase.

    Conditions for drift detection:

    • skip_read must be set to false.
    • read_url, read_method, and read_response_codes must be configured.

    Behavior:

    • If the live response diverges from the stored response (including unexpected HTTP status codes), Terraform will plan a replace (destroy and then recreate the resource).
    • Note: Drift remediation is replace-only; there is no mechanism for in-place updates of the remote state.

    Handling volatile data: To prevent unnecessary replacements caused by changing values in a JSON response, use the ignore_response_fields option to exclude specific volatile JSON fields from the comparison.