Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Ephemeral Values prototype #35078

Draft
wants to merge 32 commits into
base: main
Choose a base branch
from
Draft

Commits on May 9, 2024

  1. lang: A new mark type for ephemeral values

    This isn't actually used anywhere yet. We'll introduce uses of it in
    subsequent commits.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    7f1ed47 View commit details
    Browse the repository at this point in the history
  2. experiments: "ephemeral_values" language experiment

    This doesn't actually do anything yet, but in future commits it will
    enable some new language features for marking input variables and output
    values as "ephemeral", meaning that they don't get saved as part of
    state snapshots or saved plan files.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    0217d4f View commit details
    Browse the repository at this point in the history
  3. configs: Variables and outputs can be "ephemeral"

    When the ephemeral_values experiment is active, a module author can
    designate individual input variables and output values as being
    "ephemeral", which doesn't currently do anything but in future commits
    will represent that the values can be used only in locations that don't
    require Terraform to persist the value as part of state snapshots or
    saved plan files.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    3126ddf View commit details
    Browse the repository at this point in the history
  4. terraform: Initial partial support for ephemeral values

    This is a checkpoint commit on the path to supporting ephemeral values as
    a cross-cutting concern in the Terraform language. An ephemeral value is
    one that lives only in RAM during a single phase and so cannot persist
    from the plan phase to the apply phase, or between consecutive plan/apply
    rounds.
    
    Terraform tracks whether each value is ephemeral using the cty "marks"
    concept, thus achieving the same dynamic analysis as we already employ for
    the concept of "sensitive values" that prevents displaying a value in the
    user interface.
    
    This commit is just a starting point which gets some of the basics into
    place:
     - input variables and output values can both be statically declared as
       being ephemeral. Only ephemeral inputs/outputs can have ephemeral values
       assigned to them, and the recipient of the value sees it as ephemeral
       even if the assigned value was not already ephemeral.
    
       This creates a dynamic analysis cutoff point at module boundaries so
       that it's possible to determine in isolation whether a single module is
       using ephemeral values correctly, without having to test it in every
       possible calling context.
     - Managed and data resources cannot have ephemeral values assigned into
       their configurations because Terraform and providers both expect the
       resource attributes to persist between phases.
     - Ephemeral values _can_ be used in provider and provisioner
       configurations, because both of those effectively meet the definition
       of the new "ephemeral" concept despite it not previously having a name.
     - Ephemeral markings propagate through all of the built-in language
       features for dynamic analysis purposes, largely relying on cty's efforts
       to do that in similar vein as for sensitive marks. In particular,
       it's possible to define an ephemeral value whose expression produces
       an ephemeral result, and passing ephemeral values to functions should
       propagate the ephemeral mark to the results when appropriate. (I've not
       yet thoroughly reviewed all of the built-in functions for correct
       marks handling though, so there may be some gaps to address in later
       commits.)
    
    The next step for this work will be to change the modules runtime to have
    support for a workflow involving ephemeral _root_ input variables, where
    their values must be re-supplied during the apply phase. That will then
    achieve (in experimental capacity) the first goal of ephemeral values: to
    be able to provide non-persistent settings such as time-limited API tokens
    to use in provider configuration blocks.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    9151909 View commit details
    Browse the repository at this point in the history
  5. plans: Track input variables that must be re-supplied during apply

    We'll use this to track what subset of the ephemeral input variables were
    set in the planning options, and which ones must therefore be re-supplied
    in the apply phase options.
    
    This new plan field is not yet populated anywhere. The uses of this will
    follow in subsequent commits.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    9db5857 View commit details
    Browse the repository at this point in the history
  6. terraform: Check for required input variables during the apply phase

    The new concept of "ephemeral input variables" creates the possibility of
    needing to provide an input variable value during the apply phase, rather
    than just retaining it in the plan.
    
    Now we'll remember in the plan the names of the variables that need to be
    re-supplied during apply -- that is, any ephemeral values whose plan-time
    values were non-null -- and then check at the start of the apply phase
    whether those variables (and _only_ those variables) were provided in the
    planning options.
    
    This doesn't yet update Terraform CLI to actually populate this stuff, so
    as of this commit any plan with apply-time variables is effectively
    unapplyable. We'll deal with that in future commits.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    a2c26e5 View commit details
    Browse the repository at this point in the history
  7. backend/local: Handle apply-time values for ephemeral input variables

    When the ephemeral variables experiment is active we can potentially have
    input variables whose values need to be provided separately in both the
    plan and apply phases, as a compromise to avoid writing those values as
    part of a saved plan file and to allow the given value to vary between
    the two phases if necessary.
    
    The CLI layer must therefore re-process the given input variable values
    during the apply phase whenever this experiment is active for the root
    module and the plan recorded at least one apply-time variable name.
    
    To reduce the risk of this new logic accidentally impacting
    non-experimental usage, the whole call is guarded by whether the root
    module is participating in the experiment. Checking just the root module
    is sufficient here because only the root input variables are directly
    handled by the CLI layer; input variables for descendent modules are
    handled entirely within the modules runtime.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    cc0bb71 View commit details
    Browse the repository at this point in the history
  8. Configuration menu
    Copy the full SHA
    d4cf5a2 View commit details
    Browse the repository at this point in the history
  9. addrs: EphemeralResourceMode

    This is the new resource mode for ephemeral resources.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    e4ec3d3 View commit details
    Browse the repository at this point in the history
  10. configs: Experimental support for ephemeral resources

    Ephemeral resources, declared using "ephemeral" blocks, represent objects
    that are instantiated only for the duration of a single Terraform phase,
    and are intended for uses such as temporary network tunnels or
    time-limited leases of sensitive values from stores such as HashiCorp
    Vault.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    2cd0271 View commit details
    Browse the repository at this point in the history
  11. terraform provider: terraform_random_number ephemeral resource type

    Similar to terraform_data, this is really just here to use as a
    placeholder when one needs an ephemeral resource for some reason but
    doesn't need any specific one.
    
    This might get removed before the ephemeral_values experiment gets
    stabilized. For now it's here to use as an initial testing vehicle since
    we don't have any mechanism for offering experimental features in the
    provider plugin protocol, whereas this provider is not a plugin.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    faf08fa View commit details
    Browse the repository at this point in the history
  12. addrs: ParseRef and ParseTarget support ephemeral resource addresses

    This change is not shippable as-is because it changes the interpretation of
    any reference starting with "ephemeral.", which would previously have
    referred to a managed resource type belonging to a provider whose local
    name is "ephemeral".
    
    Therefore this initial attempt is only for prototyping purposes and would
    need to be modified in some way in order to be shippable. It will
    presumably need some sort of opt-in within the calling module so that the
    old interpretation can be preserved by default.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    2504b36 View commit details
    Browse the repository at this point in the history
  13. terraform: Add ephemeral resources to the graph, and validate refs

    This is not yet sufficient to actually open/renew/close ephemeral resource
    instances, and so as of this commit a module including ephemeral resources
    will misbehave. Further work in subsequent commits.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    e0bed89 View commit details
    Browse the repository at this point in the history
  14. lang: Basic awareness of ephemeral resource evaluation

    There is not yet the needed support in the concrete evaluation data
    implementation, but this at least now knows to call it and collect the
    results.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    dc14058 View commit details
    Browse the repository at this point in the history
  15. terraform: Don't panic when visiting ephemeral resource nodes

    We don't yet do anything useful when we get there, but we do at least fail
    in a vaguely-graceful way.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    a1cb700 View commit details
    Browse the repository at this point in the history
  16. terraform: Graph nodes for closing ephemeral resource instances

    For now these graph nodes don't actually do anything, but the graph shape
    is at least plausible for what we'll need.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    ce438c4 View commit details
    Browse the repository at this point in the history
  17. Configuration menu
    Copy the full SHA
    d6f04d1 View commit details
    Browse the repository at this point in the history
  18. Configuration menu
    Copy the full SHA
    8b98ccd View commit details
    Browse the repository at this point in the history
  19. terraform: "Close" the graph walker when a graph walker is complete

    We now need to clean up any straggling ephemeral resource instances before
    we complete each graph walk, and ephemeral resource instances are
    ultimately owned by the graph walker, so the graph walker now has a Close
    method that's responsible for cleaning up anything that the walker owns
    which needs to be explicitly closed at the end of a walk.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    05d61a4 View commit details
    Browse the repository at this point in the history
  20. Configuration menu
    Copy the full SHA
    4dedb78 View commit details
    Browse the repository at this point in the history
  21. terraform: Close provider after ephemeral resources closed

    Because ephemeralResourceCloseTransformer runs very late in the transform
    sequence, it's too late to get provider open and close nodes associated
    with it automatically.
    
    We don't actually need to worry about the provider _open_ dependency
    because our close node always depends on all of our open nodes and they
    will in turn depend on the provider open they need. But for close we need
    to delay closing the provider until all of the associated ephemeral
    resources have been closed, so we need to do a little fixup:
    
    If any of particular ephemeral resource's open nodes have provider close
    nodes depending on them, those provider close nodes should also depend
    on the ephemeral resource close node. That then describes that the
    provider should remain open for as long as at least one ephemeral resource
    instance owned by that provider remains live, which makes it okay for us
    to do our periodic background renew requests and our final close requests.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    2e79da5 View commit details
    Browse the repository at this point in the history
  22. terraform: Use GraphNodeReferencer directly for ephemeral resource an…

    …alysis
    
    Previously we had a special interface graphNodeEphemeralResourceConsumer
    and a helper for implementing it in terms of GraphNodeReferencer, but
    for the moment we'll just use GraphNodeReferencer directly with that
    helper because that gives us broad coverage across many node types without
    having to make such sprawling changes just to support a prototype.
    
    The separated interface design might return later if we discover a need for
    a node to report that it uses an ephemeral resource without actually
    including any expression references for it, but we'll wait to see if that
    additional complexity is actually needed.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    5d00b8c View commit details
    Browse the repository at this point in the history
  23. terraform: Expression evaluator can deal with ephemeral resource refs

    Ephemeral resources work quite differently than managed or data resources
    in that their instances live only in memory and are never persisted, and
    in that we need to handle the possibility of the object having become
    invalid by the time we're evaluating a reference expression.
    
    Since we're just prototyping ephemeral resources for now, this works as
    a totally separate codepath in the evaluator. The resource reference
    handling in the evaluator is long overdue for being reworked so that it
    doesn't depend so directly on the implementation details of how we
    keep track of resources, and the new ephemeral codepath is perhaps a
    simplified example of what that might look like in future, but for now it's
    used only for ephemeral resources to limit the invasiveness of this
    prototype.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    8b48a5b View commit details
    Browse the repository at this point in the history
  24. terraform: Never prune "unused" ephemeral resource nodes

    I'm honestly not really sure yet how to explain _why_ ephemeral resource
    nodes are getting pruned when they shouldn't; for the sake of prototyping
    this is just a hard-coded special exception to just not consider them
    at all in the pruneUnusedNodesTransformer.
    
    The later ephemeralResourceCloseTransformer has its own logic for deciding
    that an ephemeral resource isn't actually needed in the current graph
    and pruning both their open and close nodes, so these will still get
    pruned but it will happen in different circumstances and based on a later
    form of the graph with more nodes and edges already present, thus
    preventing some cases of ephemeral resources being pruned when they
    shouldn't be.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    7f7d2f4 View commit details
    Browse the repository at this point in the history
  25. plans+states: Reject attempts to persist ephemeral resources

    The modules runtime should always use a different strategy to keep track
    of live ephemeral resource instances, and should never persist them in
    the plan or state.
    
    These checks are here just to reduce the risk that a bug in the modules
    runtime could inadvertently result in an ephemeral resource instance being
    persisted. This is a bit of a "defense-in-depth" strategy, because the
    state and plan types all have most of their fields exported and so we can't
    be sure that all modifications will go through the mutation methods.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    9dc96e1 View commit details
    Browse the repository at this point in the history
  26. terraform: Don't try to write ephemeral resources to plan or state

    This is just enough to skip writing and reading ephemeral resources and
    their instances in the plan and state, so that we can reach the code that
    manages them in their own separate data structure.
    
    This relies on the new idea of some resource modes not being persisted
    between rounds and not being persisted from plan to apply, although for
    now EphemeralResourceMode is the only mode that doesn't do both of those
    things.
    apparentlymart committed May 9, 2024
    Configuration menu
    Copy the full SHA
    65ce265 View commit details
    Browse the repository at this point in the history

Commits on May 10, 2024

  1. command: "terraform apply" accepts variable values with saved plan

    To support ephemeral values we need a more complicated set of rules about
    what input variables can and must be set when applying a saved plan. The
    command itself does not have enough information to implement those rules
    itself, so we'll let them pass through and check this in the local
    backend's apply phase instead.
    
    The local backend's apply phase already has basic support for dealing with
    apply-time variable values, so this just removes the blocker that was
    preventing values from reaching that logic.
    apparentlymart committed May 10, 2024
    Configuration menu
    Copy the full SHA
    cb5006f View commit details
    Browse the repository at this point in the history
  2. terraform: Propagate apply-time variables from plan to apply

    We need to remember which ephemeral values were set during planning so that
    we can require them to be set again (possibly to a different value) during
    the apply step.
    apparentlymart committed May 10, 2024
    Configuration menu
    Copy the full SHA
    23ebf2d View commit details
    Browse the repository at this point in the history
  3. builtin/providers/terraform: Prepare for more ephemeral resource types

    Instead of a test for whether the type name is different than the one we
    expect, we'll use a switch statement. This does nothing for now, but
    a future commit will add a new ephemeral resource type that's intended only
    for prototyping, exploiting the fact that this particular provider can
    offer ephemeral resource types without us first extending the provider
    plugin protocol with that concept.
    apparentlymart committed May 10, 2024
    Configuration menu
    Copy the full SHA
    6884a65 View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    0a1b9d3 View commit details
    Browse the repository at this point in the history
  5. builtin/providers/terraform: terraform_ssh_tunnels ephemeral resource…

    … type
    
    This is here only for the purposes of prototyping ephemeral resources. If
    we move forward with a "real" implementation then something like this would
    be better placed in a separate SSH provider, rather than built into
    Terraform CLI itself.
    
    This is just a basic implementation to get started with. It's probably
    not very robust and will probably need fixes and additions in future
    commits.
    apparentlymart committed May 10, 2024
    Configuration menu
    Copy the full SHA
    de22ac5 View commit details
    Browse the repository at this point in the history

Commits on May 11, 2024

  1. terraform: Ephemeral resource close comes after provider close

    When a provider configuration is using an ephemeral resource, we need the
    closure of the resource instances to depend on the closure of the provider
    instance because otherwise we'll leave the ephemeral resource instance
    live only long enough to configure the provider, and that's useless for
    taking any other actions with the provider after it's been configured.
    apparentlymart committed May 11, 2024
    Configuration menu
    Copy the full SHA
    9b8cb54 View commit details
    Browse the repository at this point in the history