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

Refined Unknown Values, allowing some operations with unknown values to produce known results #33234

Merged
merged 8 commits into from
May 24, 2023

Commits on May 24, 2023

  1. Configuration menu
    Copy the full SHA
    1ef550e View commit details
    Browse the repository at this point in the history
  2. lang/funcs: Non-null refinements for various functions

    cty's new "refinements" concept allows us to reduce the range of unknown
    values from our functions. This initial changeset focuses only on
    declaring which functions are guaranteed to return a non-null result,
    which is a helpful baseline refinement because it allows "== null" and
    "!= null" tests to produce known results even when the given value is
    otherwise unknown.
    
    This commit also includes some updates to test results that are now
    refined based on cty's own built-in refinement behaviors, just as a
    result of us having updated cty in the previous commit.
    apparentlymart committed May 24, 2023
    Configuration menu
    Copy the full SHA
    c912970 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    696cd68 View commit details
    Browse the repository at this point in the history
  4. builtin/providers/terraform: terraform_data "id" is guaranteed non-null

    The "id" attribute of this resource type is generated by the provider
    itself and can never be null, so we'll refine the range of its unknown
    result in case that helps downstream expressions to produce known results
    even when the exact value hasn't yet been planned.
    apparentlymart committed May 24, 2023
    Configuration menu
    Copy the full SHA
    691018d View commit details
    Browse the repository at this point in the history
  5. lang/funcs: startswith considers string prefix refinement

    If the string to be tested is an unknown value that's been refined with
    a prefix and the prefix we're being asked to test is in turn a prefix of
    that known prefix then we can return a known answer despite the inputs
    not being fully known.
    
    There are also some other similar deductions we can make about other
    combinations of inputs.
    
    This extra analysis could be useful in a custom condition check that
    requires a string with a particular prefix, since it can allow the
    condition to fail even on partially-unknown input, thereby giving earlier
    feedback about a problem.
    apparentlymart committed May 24, 2023
    Configuration menu
    Copy the full SHA
    81c15f9 View commit details
    Browse the repository at this point in the history
  6. plans/objchange: Providers must honor their unknown value refinements

    If the original value was unknown but its range was refined then the
    provider must return a value that is within the refined range, because
    otherwise downstream planning decisions could be invalidated.
    
    This relies on cty's definition of whether a value is in a refined range,
    which has pretty good coverage for the "false" case and so should give a
    pretty good signal, but it'll probably improve over time and so providers
    must not rely on any loopholes in the current implementation and must
    keep their promises even if Terraform can't currently check them.
    apparentlymart committed May 24, 2023
    Configuration menu
    Copy the full SHA
    dfe5e1d View commit details
    Browse the repository at this point in the history
  7. plans/objchange: Don't consider refinements when validating plans

    Providers that existed prior to refinements (all of them, at the time of
    writing) cannot preserve refinements sent in unknown values in the
    configuration, and even if one day providers _are_ aware of refinements
    there we might add new ones that existing providers don't know how to
    handle.
    
    For that reason we'll absolve providers of the responsibility of
    preserving refinements from config into plan by fixing some cases where
    we were incorrectly using RawEquals to compare values; that function isn't
    appropriate for comparing values that might be unknown.
    
    However, to avoid a disruptive change right now this initial fix just
    strips off the refinements before comparing. Ideally this should be using
    Value.Equals and handling unknown values more explicitly, but we'll save
    that for a possible later improvement.
    
    This does not include a similar exception for validating whether a final
    value conforms to a plan because the plan value and the final value are
    both produced by the same provider and so providers ought to be able to
    be consistent with their _own_ treatment of refinements, if any.
    Configuration is special because Terraform itself generates that, and so
    it can potentially contain refinements that a particular provider has no
    awareness of.
    apparentlymart committed May 24, 2023
    Configuration menu
    Copy the full SHA
    4c439b0 View commit details
    Browse the repository at this point in the history
  8. docs: Describe the plugin protocol encoding of refined unknown values

    This is actually a description of the "cty" library's encoding of refined
    values, but from the perspective of the plugin protocol it's an
    implementation detail that Terraform Core outsources that to a third-party
    library, and current server-side implementations of the protocol use an
    independent implementation of this format which will need to be compatible
    with what cty does.
    apparentlymart committed May 24, 2023
    Configuration menu
    Copy the full SHA
    e0ef274 View commit details
    Browse the repository at this point in the history