configs

package
v0.0.0-...-c924774 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 29, 2024 License: MPL-2.0 Imports: 30 Imported by: 0

Documentation

Overview

Package configs contains types that represent OpenTofu configurations and the different elements thereof.

The functionality in this package can be used for some static analyses of OpenTofu configurations, but this package generally exposes representations of the configuration source code rather than the result of evaluating these objects. The sibling package "lang" deals with evaluation of structures and expressions in the configuration.

Due to its close relationship with HCL, this package makes frequent use of types from the HCL API, including raw HCL diagnostic messages. Such diagnostics can be converted into OpenTofu-flavored diagnostics, if needed, using functions in the sibling package tfdiags.

The Parser type is the main entry-point into this package. The LoadConfigDir method can be used to load a single module directory, and then a full configuration (including any descendent modules) can be produced using the top-level BuildConfig method.

Index

Constants

View Source
const (
	// ApplyTestCommand causes the run block to execute a OpenTofu apply
	// operation.
	ApplyTestCommand TestCommand = 0

	// PlanTestCommand causes the run block to execute a OpenTofu plan
	// operation.
	PlanTestCommand TestCommand = 'P'

	// NormalTestMode causes the run block to execute in plans.NormalMode.
	NormalTestMode TestMode = 0

	// RefreshOnlyTestMode causes the run block to execute in
	// plans.RefreshOnlyMode.
	RefreshOnlyTestMode TestMode = 'R'
)
View Source
const (
	DefaultTestDirectory = "tests"
)

Variables

View Source
var ResourceBlockSchema = &hcl.BodySchema{
	Attributes: commonResourceAttributes,
	Blocks: []hcl.BlockHeaderSchema{
		{Type: "locals"},
		{Type: "lifecycle"},
		{Type: "connection"},
		{Type: "provisioner", LabelNames: []string{"type"}},
		{Type: "_"},
	},
}

ResourceBlockSchema is the schema for a resource or data resource type within OpenTofu.

This schema is public as it is required elsewhere in order to validate and use generated config.

Functions

func IsEmptyDir

func IsEmptyDir(path string) (bool, error)

IsEmptyDir returns true if the given filesystem path contains no OpenTofu configuration files.

Unlike the methods of the Parser type, this function always consults the real filesystem, and thus it isn't appropriate to use when working with configuration loaded from a plan file.

func IsIgnoredFile

func IsIgnoredFile(name string) bool

IsIgnoredFile returns true if the given filename (which must not have a directory path ahead of it) should be ignored as e.g. an editor swap file.

func MergeBodies

func MergeBodies(base, override hcl.Body) hcl.Body

These were all moved to the hcl2shim package, but still have uses referenced from this package TODO Call sites through opentofu to these functions should be migrated to hcl2shim eventually and this file removed

func ParseProviderConfigCompact

func ParseProviderConfigCompact(traversal hcl.Traversal) (addrs.LocalProviderConfig, tfdiags.Diagnostics)

ParseProviderConfigCompact parses the given absolute traversal as a relative provider address in compact form. The following are examples of traversals that can be successfully parsed as compact relative provider configuration addresses:

  • aws
  • aws.foo

This function will panic if given a relative traversal.

If the returned diagnostics contains errors then the result value is invalid and must not be used.

func ParseProviderConfigCompactStr

func ParseProviderConfigCompactStr(str string) (addrs.LocalProviderConfig, tfdiags.Diagnostics)

ParseProviderConfigCompactStr is a helper wrapper around ParseProviderConfigCompact that takes a string and parses it with the HCL native syntax traversal parser before interpreting it.

This should be used only in specialized situations since it will cause the created references to not have any meaningful source location information. If a reference string is coming from a source that should be identified in error messages then the caller should instead parse it directly using a suitable function from the HCL API and pass the traversal itself to ParseProviderConfigCompact.

Error diagnostics are returned if either the parsing fails or the analysis of the traversal fails. There is no way for the caller to distinguish the two kinds of diagnostics programmatically. If error diagnostics are returned then the returned address is invalid.

func SynthBody

func SynthBody(filename string, values map[string]cty.Value) hcl.Body

Types

type Backend

type Backend struct {
	Type   string
	Config hcl.Body

	TypeRange hcl.Range
	DeclRange hcl.Range
}

Backend represents a "backend" block inside a "terraform" block in a module or file.

func (*Backend) Hash

func (b *Backend) Hash(schema *configschema.Block) int

Hash produces a hash value for the reciever that covers the type and the portions of the config that conform to the given schema.

If the config does not conform to the schema then the result is not meaningful for comparison since it will be based on an incomplete result.

As an exception, required attributes in the schema are treated as optional for the purpose of hashing, so that an incomplete configuration can still be hashed. Other errors, such as extraneous attributes, have no such special case.

type Check

type Check struct {
	Name string

	DataResource *Resource
	Asserts      []*CheckRule

	DeclRange hcl.Range
}

Check represents a configuration defined check block.

A check block contains 0-1 data blocks, and 0-n assert blocks. The check block will load the data block, and execute the assert blocks as check rules during the plan and apply OpenTofu operations.

func (Check) Accessible

func (c Check) Accessible(addr addrs.Referenceable) bool

func (Check) Addr

func (c Check) Addr() addrs.Check

type CheckRule

type CheckRule struct {
	// Condition is an expression that must evaluate to true if the condition
	// holds or false if it does not. If the expression produces an error then
	// that's considered to be a bug in the module defining the check.
	//
	// The available variables in a condition expression vary depending on what
	// a check is attached to. For example, validation rules attached to
	// input variables can only refer to the variable that is being validated.
	Condition hcl.Expression

	// ErrorMessage should be one or more full sentences, which should be in
	// English for consistency with the rest of the error message output but
	// can in practice be in any language. The message should describe what is
	// required for the condition to return true in a way that would make sense
	// to a caller of the module.
	//
	// The error message expression has the same variables available for
	// interpolation as the corresponding condition.
	ErrorMessage hcl.Expression

	DeclRange hcl.Range
}

CheckRule represents a configuration-defined validation rule, precondition, or postcondition. Blocks of this sort can appear in a few different places in configuration, including "validation" blocks for variables, and "precondition" and "postcondition" blocks for resources.

type CloudConfig

type CloudConfig struct {
	Config hcl.Body

	DeclRange hcl.Range
}

Cloud represents a "cloud" block inside a "terraform" block in a module or file.

func (*CloudConfig) ToBackendConfig

func (c *CloudConfig) ToBackendConfig() Backend

type Config

type Config struct {
	// RootModule points to the Config for the root module within the same
	// module tree as this module. If this module _is_ the root module then
	// this is self-referential.
	Root *Config

	// ParentModule points to the Config for the module that directly calls
	// this module. If this is the root module then this field is nil.
	Parent *Config

	// Path is a sequence of module logical names that traverse from the root
	// module to this config. Path is empty for the root module.
	//
	// This should only be used to display paths to the end-user in rare cases
	// where we are talking about the static module tree, before module calls
	// have been resolved. In most cases, an addrs.ModuleInstance describing
	// a node in the dynamic module tree is better, since it will then include
	// any keys resulting from evaluating "count" and "for_each" arguments.
	Path addrs.Module

	// ChildModules points to the Config for each of the direct child modules
	// called from this module. The keys in this map match the keys in
	// Module.ModuleCalls.
	Children map[string]*Config

	// Module points to the object describing the configuration for the
	// various elements (variables, resources, etc) defined by this module.
	Module *Module

	// CallRange is the source range for the header of the module block that
	// requested this module.
	//
	// This field is meaningless for the root module, where its contents are undefined.
	CallRange hcl.Range

	// SourceAddr is the source address that the referenced module was requested
	// from, as specified in configuration. SourceAddrRaw is the same
	// information, but as the raw string the user originally entered.
	//
	// These fields are meaningless for the root module, where their contents are undefined.
	SourceAddr    addrs.ModuleSource
	SourceAddrRaw string

	// SourceAddrRange is the location in the configuration source where the
	// SourceAddr value was set, for use in diagnostic messages.
	//
	// This field is meaningless for the root module, where its contents are undefined.
	SourceAddrRange hcl.Range

	// Version is the specific version that was selected for this module,
	// based on version constraints given in configuration.
	//
	// This field is nil if the module was loaded from a non-registry source,
	// since versions are not supported for other sources.
	//
	// This field is meaningless for the root module, where it will always
	// be nil.
	Version *version.Version
}

A Config is a node in the tree of modules within a configuration.

The module tree is constructed by following ModuleCall instances recursively through the root module transitively into descendent modules.

A module tree described in *this* package represents the static tree represented by configuration. During evaluation a static ModuleNode may expand into zero or more module instances depending on the use of count and for_each configuration attributes within each call.

func BuildConfig

func BuildConfig(root *Module, walker ModuleWalker) (*Config, hcl.Diagnostics)

BuildConfig constructs a Config from a root module by loading all of its descendent modules via the given ModuleWalker.

The result is a module tree that has so far only had basic module- and file-level invariants validated. If the returned diagnostics contains errors, the returned module tree may be incomplete but can still be used carefully for static analysis.

func NewEmptyConfig

func NewEmptyConfig() *Config

NewEmptyConfig constructs a single-node configuration tree with an empty root module. This is generally a pretty useless thing to do, so most callers should instead use BuildConfig.

func (*Config) AllModules

func (c *Config) AllModules() []*Config

AllModules returns a slice of all the receiver and all of its descendent nodes in the module tree, in the same order they would be visited by DeepEach.

func (*Config) CheckCoreVersionRequirements

func (c *Config) CheckCoreVersionRequirements() hcl.Diagnostics

func (*Config) DeepEach

func (c *Config) DeepEach(cb func(c *Config))

DeepEach calls the given function once for each module in the tree, starting with the receiver.

A parent is always called before its children and children of a particular node are visited in lexicographic order by their names.

func (*Config) Depth

func (c *Config) Depth() int

Depth returns the number of "hops" the receiver is from the root of its module tree, with the root module having a depth of zero.

func (*Config) Descendent

func (c *Config) Descendent(path addrs.Module) *Config

Descendent returns the descendent config that has the given path beneath the receiver, or nil if there is no such module.

The path traverses the static module tree, prior to any expansion to handle count and for_each arguments.

An empty path will just return the receiver, and is therefore pointless.

func (*Config) DescendentForInstance

func (c *Config) DescendentForInstance(path addrs.ModuleInstance) *Config

DescendentForInstance is like Descendent except that it accepts a path to a particular module instance in the dynamic module graph, returning the node from the static module graph that corresponds to it.

All instances created by a particular module call share the same configuration, so the keys within the given path are disregarded.

func (*Config) EntersNewPackage

func (c *Config) EntersNewPackage() bool

EntersNewPackage returns true if this call is to an external module, either directly via a remote source address or indirectly via a registry source address.

Other behaviors in OpenTofu may treat package crossings as a special situation, because that indicates that the caller and callee can change independently of one another and thus we should disallow using any features where the caller assumes anything about the callee other than its input variables, required provider configurations, and output values.

It's not meaningful to ask if the Config representing the root module enters a new package because the root module is always outside of all module packages, and so this function will arbitrarily return false in that case.

func (*Config) ProviderForConfigAddr

func (c *Config) ProviderForConfigAddr(addr addrs.LocalProviderConfig) addrs.Provider

ProviderForConfigAddr returns the FQN for a given addrs.ProviderConfig, first by checking for the provider in module.ProviderRequirements and falling back to addrs.NewDefaultProvider if it is not found.

func (*Config) ProviderRequirements

func (c *Config) ProviderRequirements() (getproviders.Requirements, hcl.Diagnostics)

ProviderRequirements searches the full tree of modules under the receiver for both explicit and implicit dependencies on providers.

The result is a full manifest of all of the providers that must be available in order to work with the receiving configuration.

If the returned diagnostics includes errors then the resulting Requirements may be incomplete.

func (*Config) ProviderRequirementsByModule

func (c *Config) ProviderRequirementsByModule() (*ModuleRequirements, hcl.Diagnostics)

ProviderRequirementsByModule searches the full tree of modules under the receiver for both explicit and implicit dependencies on providers, constructing a tree where the requirements are broken out by module.

If the returned diagnostics includes errors then the resulting Requirements may be incomplete.

func (*Config) ProviderRequirementsShallow

func (c *Config) ProviderRequirementsShallow() (getproviders.Requirements, hcl.Diagnostics)

ProviderRequirementsShallow searches only the direct receiver for explicit and implicit dependencies on providers. Descendant modules are ignored.

If the returned diagnostics includes errors then the resulting Requirements may be incomplete.

func (*Config) ProviderTypes

func (c *Config) ProviderTypes() []addrs.Provider

ProviderTypes returns the FQNs of each distinct provider type referenced in the receiving configuration.

This is a helper for easily determining which provider types are required to fully interpret the configuration, though it does not include version information and so callers are expected to have already dealt with provider version selection in an earlier step and have identified suitable versions for each provider.

func (*Config) ResolveAbsProviderAddr

func (c *Config) ResolveAbsProviderAddr(addr addrs.ProviderConfig, inModule addrs.Module) addrs.AbsProviderConfig

ResolveAbsProviderAddr returns the AbsProviderConfig represented by the given ProviderConfig address, which must not be nil or this method will panic.

If the given address is already an AbsProviderConfig then this method returns it verbatim, and will always succeed. If it's a LocalProviderConfig then it will consult the local-to-FQN mapping table for the given module to find the absolute address corresponding to the given local one.

The module address to resolve local addresses in must be given in the second argument, and must refer to a module that exists under the receiver or else this method will panic.

func (*Config) TransformForTest

func (c *Config) TransformForTest(run *TestRun, file *TestFile) (func(), hcl.Diagnostics)

TransformForTest prepares the config to execute the given test.

This function directly edits the config that is to be tested, and returns a function that will reset the config back to its original state.

Tests will call this before they execute, and then call the deferred function to reset the config before the next test.

func (*Config) VerifyDependencySelections

func (c *Config) VerifyDependencySelections(depLocks *depsfile.Locks) []error

VerifyDependencySelections checks whether the given locked dependencies are acceptable for all of the version constraints reported in the configuration tree represented by the reciever.

This function will errors only if any of the locked dependencies are out of range for corresponding constraints in the configuration. If there are multiple inconsistencies then it will attempt to describe as many of them as possible, rather than stopping at the first problem.

It's typically the responsibility of "tofu init" to change the locked dependencies to conform with the configuration, and so VerifyDependencySelections is intended for other commands to check whether it did so correctly and to catch if anything has changed in configuration since the last "tofu init" which requires re-initialization. However, it's up to the caller to decide how to advise users recover from these errors, because the advise can vary depending on what operation the user is attempting.

type Connection

type Connection struct {
	Config hcl.Body

	DeclRange hcl.Range
}

Connection represents a "connection" block when used within either a "resource" or "provisioner" block in a module or file.

type Container

type Container interface {
	// Accessible should return true if the resource specified by addr can
	// reference other items within this Container.
	//
	// Typically, that means that addr will either be the container itself or
	// something within the container.
	Accessible(addr addrs.Referenceable) bool
}

Container provides an interface for scoped resources.

Any resources contained within a Container should not be accessible from outside the container.

type File

type File struct {
	CoreVersionConstraints []VersionConstraint

	ActiveExperiments experiments.Set

	Backends          []*Backend
	CloudConfigs      []*CloudConfig
	ProviderConfigs   []*Provider
	ProviderMetas     []*ProviderMeta
	RequiredProviders []*RequiredProviders
	Encryptions       []*config.EncryptionConfig

	Variables []*Variable
	Locals    []*Local
	Outputs   []*Output

	ModuleCalls []*ModuleCall

	ManagedResources []*Resource
	DataResources    []*Resource

	Moved   []*Moved
	Import  []*Import
	Removed []*Removed

	Checks []*Check
}

File describes the contents of a single configuration file.

Individual files are not usually used alone, but rather combined together with other files (conventionally, those in the same directory) to produce a *Module, using NewModule.

At the level of an individual file we represent directly the structural elements present in the file, without any attempt to detect conflicting declarations. A File object can therefore be used for some basic static analysis of individual elements, but must be built into a Module to detect duplicate declarations.

type Import

type Import struct {
	ID hcl.Expression

	// To is the address HCL expression given in the `import` block configuration.
	// It supports the following address formats:
	// - aws_s3_bucket.my_bucket
	// - module.my_module.aws_s3_bucket.my_bucket
	// - aws_s3_bucket.my_bucket["static_key"]
	// - module.my_module[0].aws_s3_bucket.my_buckets["static_key"]
	// - aws_s3_bucket.my_bucket[expression]
	// - module.my_module[expression].aws_s3_bucket.my_buckets[expression]
	// A dynamic instance key supports a dynamic expression like - a variable, a local, a condition (for example,
	//  ternary), a resource block attribute, a data block attribute, etc.
	To hcl.Expression
	// StaticTo is the corresponding resource and module that the address is referring to. When decoding, as long
	// as the `to` field is in the accepted format, we could determine the actual modules and resource that the
	// address represents. However, we do not yet know for certain what module instance and resource instance this
	// address refers to. So, Static import is mainly used to figure out the Module and Resource, and Provider of the
	// import target resource
	// If we could not determine the StaticTo when decoding the block, then the address is in an unacceptable format
	StaticTo addrs.ConfigResource
	// ResolvedTo will be a reference to the resource instance of the import target, if it can be resolved when decoding
	// the `import` block. If the `to` field does not represent a static address
	// (for example: module.my_module[var.var1].aws_s3_bucket.bucket), then this will be nil.
	// However, if the address is static and can be fully resolved at decode time
	// (for example: module.my_module[2].aws_s3_bucket.bucket), then this will be a reference to the resource instance's
	// address
	// Mainly used for early validations on the import block address, for example making sure there are no duplicate
	// import blocks targeting the same resource
	ResolvedTo *addrs.AbsResourceInstance

	ForEach hcl.Expression

	ProviderConfigRef *ProviderConfigRef
	Provider          addrs.Provider

	DeclRange         hcl.Range
	ProviderDeclRange hcl.Range
}

type Local

type Local struct {
	Name string
	Expr hcl.Expression

	DeclRange hcl.Range
}

Local represents a single entry from a "locals" block in a module or file. The "locals" block itself is not represented, because it serves only to provide context for us to interpret its contents.

func (*Local) Addr

func (l *Local) Addr() addrs.LocalValue

Addr returns the address of the local value declared by the receiver, relative to its containing module.

type ManagedResource

type ManagedResource struct {
	Connection   *Connection
	Provisioners []*Provisioner

	CreateBeforeDestroy bool
	PreventDestroy      bool
	IgnoreChanges       []hcl.Traversal
	IgnoreAllChanges    bool

	CreateBeforeDestroySet bool
	PreventDestroySet      bool
}

ManagedResource represents a "resource" block in a module or file.

type Module

type Module struct {

	// Any other caller that constructs a module directly with NewModule may
	// assign a suitable value to this attribute before using it for other
	// purposes. It should be treated as immutable by all consumers of Module
	// values.
	SourceDir string

	CoreVersionConstraints []VersionConstraint

	ActiveExperiments experiments.Set

	Backend              *Backend
	CloudConfig          *CloudConfig
	ProviderConfigs      map[string]*Provider
	ProviderRequirements *RequiredProviders
	ProviderLocalNames   map[addrs.Provider]string
	ProviderMetas        map[addrs.Provider]*ProviderMeta
	Encryption           *config.EncryptionConfig

	Variables map[string]*Variable
	Locals    map[string]*Local
	Outputs   map[string]*Output

	ModuleCalls map[string]*ModuleCall

	ManagedResources map[string]*Resource
	DataResources    map[string]*Resource

	Moved   []*Moved
	Import  []*Import
	Removed []*Removed

	Checks map[string]*Check

	Tests map[string]*TestFile
}

Module is a container for a set of configuration constructs that are evaluated within a common namespace.

func NewModule

func NewModule(primaryFiles, overrideFiles []*File) (*Module, hcl.Diagnostics)

NewModule takes a list of primary files and a list of override files and produces a *Module by combining the files together.

If there are any conflicting declarations in the given files -- for example, if the same variable name is defined twice -- then the resulting module will be incomplete and error diagnostics will be returned. Careful static analysis of the returned Module is still possible in this case, but the module will probably not be semantically valid.

func NewModuleWithTests

func NewModuleWithTests(primaryFiles, overrideFiles []*File, testFiles map[string]*TestFile) (*Module, hcl.Diagnostics)

NewModuleWithTests matches NewModule except it will also load in the provided test files.

func (*Module) CheckCoreVersionRequirements

func (m *Module) CheckCoreVersionRequirements(path addrs.Module, sourceAddr addrs.ModuleSource) hcl.Diagnostics

func (*Module) ImpliedProviderForUnqualifiedType

func (m *Module) ImpliedProviderForUnqualifiedType(pType string) addrs.Provider

ImpliedProviderForUnqualifiedType returns the provider FQN for a given type, first by looking up the type in the provider requirements map, and falling back to an implied default provider.

The intended behaviour is that configuring a provider with local name "foo" in a required_providers block will result in resources with type "foo" using that provider.

func (*Module) LocalNameForProvider

func (m *Module) LocalNameForProvider(p addrs.Provider) string

LocalNameForProvider returns the module-specific user-supplied local name for a given provider FQN, or the default local name if none was supplied.

func (*Module) ProviderForLocalConfig

func (m *Module) ProviderForLocalConfig(pc addrs.LocalProviderConfig) addrs.Provider

ProviderForLocalConfig returns the provider FQN for a given LocalProviderConfig, based on its local name.

func (*Module) ResourceByAddr

func (m *Module) ResourceByAddr(addr addrs.Resource) *Resource

ResourceByAddr returns the configuration for the resource with the given address, or nil if there is no such resource.

type ModuleCall

type ModuleCall struct {
	Name string

	SourceAddr      addrs.ModuleSource
	SourceAddrRaw   string
	SourceAddrRange hcl.Range
	SourceSet       bool

	Config hcl.Body

	Version VersionConstraint

	Count   hcl.Expression
	ForEach hcl.Expression

	Providers []PassedProviderConfig

	DependsOn []hcl.Traversal

	DeclRange hcl.Range
}

ModuleCall represents a "module" block in a module or file.

func (*ModuleCall) EntersNewPackage

func (mc *ModuleCall) EntersNewPackage() bool

EntersNewPackage returns true if this call is to an external module, either directly via a remote source address or indirectly via a registry source address.

Other behaviors in OpenTofu may treat package crossings as a special situation, because that indicates that the caller and callee can change independently of one another and thus we should disallow using any features where the caller assumes anything about the callee other than its input variables, required provider configurations, and output values.

type ModuleRequest

type ModuleRequest struct {
	// Name is the "logical name" of the module call within configuration.
	// This is provided in case the name is used as part of a storage key
	// for the module, but implementations must otherwise treat it as an
	// opaque string. It is guaranteed to have already been validated as an
	// HCL identifier and UTF-8 encoded.
	Name string

	// Path is a list of logical names that traverse from the root module to
	// this module. This can be used, for example, to form a lookup key for
	// each distinct module call in a configuration, allowing for multiple
	// calls with the same name at different points in the tree.
	Path addrs.Module

	// SourceAddr is the source address string provided by the user in
	// configuration.
	SourceAddr addrs.ModuleSource

	// SourceAddrRange is the source range for the SourceAddr value as it
	// was provided in configuration. This can and should be used to generate
	// diagnostics about the source address having invalid syntax, referring
	// to a non-existent object, etc.
	SourceAddrRange hcl.Range

	// VersionConstraint is the version constraint applied to the module in
	// configuration. This data structure includes the source range for
	// the constraint, which can and should be used to generate diagnostics
	// about constraint-related issues, such as constraints that eliminate all
	// available versions of a module whose source is otherwise valid.
	VersionConstraint VersionConstraint

	// Parent is the partially-constructed module tree node that the loaded
	// module will be added to. Callers may refer to any field of this
	// structure except Children, which is still under construction when
	// ModuleRequest objects are created and thus has undefined content.
	// The main reason this is provided is so that full module paths can
	// be constructed for uniqueness.
	Parent *Config

	// CallRange is the source range for the header of the "module" block
	// in configuration that prompted this request. This can be used as the
	// subject of an error diagnostic that relates to the module call itself,
	// rather than to either its source address or its version number.
	CallRange hcl.Range
}

ModuleRequest is used with the ModuleWalker interface to describe a child module that must be loaded.

type ModuleRequirements

type ModuleRequirements struct {
	Name         string
	SourceAddr   addrs.ModuleSource
	SourceDir    string
	Requirements getproviders.Requirements
	Children     map[string]*ModuleRequirements
	Tests        map[string]*TestFileModuleRequirements
}

ModuleRequirements represents the provider requirements for an individual module, along with references to any child modules. This is used to determine which modules require which providers.

type ModuleWalker

type ModuleWalker interface {
	// LoadModule finds and loads a requested child module.
	//
	// If errors are detected during loading, implementations should return them
	// in the diagnostics object. If the diagnostics object contains any errors
	// then the caller will tolerate the returned module being nil or incomplete.
	// If no errors are returned, it should be non-nil and complete.
	//
	// Full validation need not have been performed but an implementation should
	// ensure that the basic file- and module-validations performed by the
	// LoadConfigDir function (valid syntax, no namespace collisions, etc) have
	// been performed before returning a module.
	LoadModule(req *ModuleRequest) (*Module, *version.Version, hcl.Diagnostics)
}

A ModuleWalker knows how to find and load a child module given details about the module to be loaded and a reference to its partially-loaded parent Config.

var DisabledModuleWalker ModuleWalker

DisabledModuleWalker is a ModuleWalker that doesn't support child modules at all, and so will return an error if asked to load one.

This is provided primarily for testing. There is no good reason to use this in the main application.

type ModuleWalkerFunc

type ModuleWalkerFunc func(req *ModuleRequest) (*Module, *version.Version, hcl.Diagnostics)

ModuleWalkerFunc is an implementation of ModuleWalker that directly wraps a callback function, for more convenient use of that interface.

func (ModuleWalkerFunc) LoadModule

func (f ModuleWalkerFunc) LoadModule(req *ModuleRequest) (*Module, *version.Version, hcl.Diagnostics)

LoadModule implements ModuleWalker.

type Moved

type Moved struct {
	From *addrs.MoveEndpoint
	To   *addrs.MoveEndpoint

	DeclRange hcl.Range
}

type Output

type Output struct {
	Name        string
	Description string
	Expr        hcl.Expression
	DependsOn   []hcl.Traversal
	Sensitive   bool

	Preconditions []*CheckRule

	DescriptionSet bool
	SensitiveSet   bool

	DeclRange hcl.Range
}

Output represents an "output" block in a module or file.

func (*Output) Addr

func (o *Output) Addr() addrs.OutputValue

type Parser

type Parser struct {
	// contains filtered or unexported fields
}

Parser is the main interface to read configuration files and other related files from disk.

It retains a cache of all files that are loaded so that they can be used to create source code snippets in diagnostics, etc.

func NewParser

func NewParser(fs afero.Fs) *Parser

NewParser creates and returns a new Parser that reads files from the given filesystem. If a nil filesystem is passed then the system's "real" filesystem will be used, via afero.OsFs.

func (*Parser) AllowLanguageExperiments

func (p *Parser) AllowLanguageExperiments(allowed bool)

AllowLanguageExperiments specifies whether subsequent LoadConfigFile (and similar) calls will allow opting in to experimental language features.

If this method is never called for a particular parser, the default behavior is to disallow language experiments.

Main code should set this only for alpha or development builds. Test code is responsible for deciding for itself whether and how to call this method.

func (Parser) ConfigDirFiles

func (p Parser) ConfigDirFiles(dir string) (primary, override []string, diags hcl.Diagnostics)

ConfigDirFiles returns lists of the primary and override files configuration files in the given directory.

If the given directory does not exist or cannot be read, error diagnostics are returned. If errors are returned, the resulting lists may be incomplete.

func (Parser) ConfigDirFilesWithTests

func (p Parser) ConfigDirFilesWithTests(dir string, testDirectory string) (primary, override, tests []string, diags hcl.Diagnostics)

ConfigDirFilesWithTests matches ConfigDirFiles except it also returns the paths to any test files within the module.

func (*Parser) ForceFileSource

func (p *Parser) ForceFileSource(filename string, src []byte)

ForceFileSource artificially adds source code to the cache of file sources, as if it had been loaded from the given filename.

This should be used only in special situations where configuration is loaded some other way. Most callers should load configuration via methods of Parser, which will update the sources cache automatically.

func (*Parser) IsConfigDir

func (p *Parser) IsConfigDir(path string) bool

IsConfigDir determines whether the given path refers to a directory that exists and contains at least one OpenTofu config file (with a .tf or .tf.json extension.). Note, we explicitely exclude checking for tests here as tests must live alongside actual .tf config files.

func (*Parser) LoadConfigDir

func (p *Parser) LoadConfigDir(path string) (*Module, hcl.Diagnostics)

LoadConfigDir reads the .tf and .tf.json files in the given directory as config files (using LoadConfigFile) and then combines these files into a single Module.

If this method returns nil, that indicates that the given directory does not exist at all or could not be opened for some reason. Callers may wish to detect this case and ignore the returned diagnostics so that they can produce a more context-aware error message in that case.

If this method returns a non-nil module while error diagnostics are returned then the module may be incomplete but can be used carefully for static analysis.

This file does not consider a directory with no files to be an error, and will simply return an empty module in that case. Callers should first call Parser.IsConfigDir if they wish to recognize that situation.

.tf files are parsed using the HCL native syntax while .tf.json files are parsed using the HCL JSON syntax.

func (*Parser) LoadConfigDirWithTests

func (p *Parser) LoadConfigDirWithTests(path string, testDirectory string) (*Module, hcl.Diagnostics)

LoadConfigDirWithTests matches LoadConfigDir, but the return Module also contains any relevant .tftest.hcl files.

func (*Parser) LoadConfigFile

func (p *Parser) LoadConfigFile(path string) (*File, hcl.Diagnostics)

LoadConfigFile reads the file at the given path and parses it as a config file.

If the file cannot be read -- for example, if it does not exist -- then a nil *File will be returned along with error diagnostics. Callers may wish to disregard the returned diagnostics in this case and instead generate their own error message(s) with additional context.

If the returned diagnostics has errors when a non-nil map is returned then the map may be incomplete but should be valid enough for careful static analysis.

This method wraps LoadHCLFile, and so it inherits the syntax selection behaviors documented for that method.

func (*Parser) LoadConfigFileOverride

func (p *Parser) LoadConfigFileOverride(path string) (*File, hcl.Diagnostics)

LoadConfigFileOverride is the same as LoadConfigFile except that it relaxes certain required attribute constraints in order to interpret the given file as an overrides file.

func (*Parser) LoadHCLFile

func (p *Parser) LoadHCLFile(path string) (hcl.Body, hcl.Diagnostics)

LoadHCLFile is a low-level method that reads the file at the given path, parses it, and returns the hcl.Body representing its root. In many cases it is better to use one of the other Load*File methods on this type, which additionally decode the root body in some way and return a higher-level construct.

If the file cannot be read at all -- e.g. because it does not exist -- then this method will return a nil body and error diagnostics. In this case callers may wish to ignore the provided error diagnostics and produce a more context-sensitive error instead.

The file will be parsed using the HCL native syntax unless the filename ends with ".json", in which case the HCL JSON syntax will be used.

func (*Parser) LoadTestFile

func (p *Parser) LoadTestFile(path string) (*TestFile, hcl.Diagnostics)

LoadTestFile reads the file at the given path and parses it as a OpenTofu test file.

It references the same LoadHCLFile as LoadConfigFile, so inherits the same syntax selection behaviours.

func (*Parser) LoadValuesFile

func (p *Parser) LoadValuesFile(path string) (map[string]cty.Value, hcl.Diagnostics)

LoadValuesFile reads the file at the given path and parses it as a "values file", which is an HCL config file whose top-level attributes are treated as arbitrary key.value pairs.

If the file cannot be read -- for example, if it does not exist -- then a nil map will be returned along with error diagnostics. Callers may wish to disregard the returned diagnostics in this case and instead generate their own error message(s) with additional context.

If the returned diagnostics has errors when a non-nil map is returned then the map may be incomplete but should be valid enough for careful static analysis.

This method wraps LoadHCLFile, and so it inherits the syntax selection behaviors documented for that method.

func (*Parser) Sources

func (p *Parser) Sources() map[string][]byte

Sources returns a map of the cached source buffers for all files that have been loaded through this parser, with source filenames (as requested when each file was opened) as the keys.

type PassedProviderConfig

type PassedProviderConfig struct {
	InChild  *ProviderConfigRef
	InParent *ProviderConfigRef
}

PassedProviderConfig represents a provider config explicitly passed down to a child module, possibly giving it a new local address in the process.

type Provider

type Provider struct {
	Name       string
	NameRange  hcl.Range
	Alias      string
	AliasRange *hcl.Range // nil if no alias set

	Version VersionConstraint

	Config hcl.Body

	DeclRange hcl.Range
	// contains filtered or unexported fields
}

Provider represents a "provider" block in a module or file. A provider block is a provider configuration, and there can be zero or more configurations for each actual provider.

func (*Provider) Addr

Addr returns the address of the receiving provider configuration, relative to its containing module.

type ProviderConfigRef

type ProviderConfigRef struct {
	Name       string
	NameRange  hcl.Range
	Alias      string
	AliasRange *hcl.Range // nil if alias not set
	// contains filtered or unexported fields
}

func (*ProviderConfigRef) Addr

Addr returns the provider config address corresponding to the receiving config reference.

This is a trivial conversion, essentially just discarding the source location information and keeping just the addressing information.

func (*ProviderConfigRef) String

func (r *ProviderConfigRef) String() string

type ProviderMeta

type ProviderMeta struct {
	Provider string
	Config   hcl.Body

	ProviderRange hcl.Range
	DeclRange     hcl.Range
}

ProviderMeta represents a "provider_meta" block inside a "terraform" block in a module or file.

type Provisioner

type Provisioner struct {
	Type       string
	Config     hcl.Body
	Connection *Connection
	When       ProvisionerWhen
	OnFailure  ProvisionerOnFailure

	DeclRange hcl.Range
	TypeRange hcl.Range
}

Provisioner represents a "provisioner" block when used within a "resource" block in a module or file.

type ProvisionerOnFailure

type ProvisionerOnFailure int

ProvisionerOnFailure is an enum for valid values for on_failure options for provisioners.

const (
	ProvisionerOnFailureInvalid ProvisionerOnFailure = iota
	ProvisionerOnFailureContinue
	ProvisionerOnFailureFail
)

func (ProvisionerOnFailure) String

func (i ProvisionerOnFailure) String() string

type ProvisionerWhen

type ProvisionerWhen int

ProvisionerWhen is an enum for valid values for when to run provisioners.

const (
	ProvisionerWhenInvalid ProvisionerWhen = iota
	ProvisionerWhenCreate
	ProvisionerWhenDestroy
)

func (ProvisionerWhen) String

func (i ProvisionerWhen) String() string

type Removed

type Removed struct {
	From *addrs.RemoveEndpoint

	DeclRange hcl.Range
}

Removed represents a removed block in the configuration.

type RequiredProvider

type RequiredProvider struct {
	Name        string
	Source      string
	Type        addrs.Provider
	Requirement VersionConstraint
	DeclRange   hcl.Range
	Aliases     []addrs.LocalProviderConfig
}

RequiredProvider represents a declaration of a dependency on a particular provider version or source without actually configuring that provider. This is used in child modules that expect a provider to be passed in from their parent.

type RequiredProviders

type RequiredProviders struct {
	RequiredProviders map[string]*RequiredProvider
	DeclRange         hcl.Range
}

type Resource

type Resource struct {
	Mode    addrs.ResourceMode
	Name    string
	Type    string
	Config  hcl.Body
	Count   hcl.Expression
	ForEach hcl.Expression

	ProviderConfigRef *ProviderConfigRef
	Provider          addrs.Provider

	Preconditions  []*CheckRule
	Postconditions []*CheckRule

	DependsOn []hcl.Traversal

	TriggersReplacement []hcl.Expression

	// Managed is populated only for Mode = addrs.ManagedResourceMode,
	// containing the additional fields that apply to managed resources.
	// For all other resource modes, this field is nil.
	Managed *ManagedResource

	// Container links a scoped resource back up to the resources that contains
	// it. This field is referenced during static analysis to check whether any
	// references are also made from within the same container.
	//
	// If this is nil, then this resource is essentially public.
	Container Container

	DeclRange hcl.Range
	TypeRange hcl.Range
}

Resource represents a "resource" or "data" block in a module or file.

func (*Resource) Addr

func (r *Resource) Addr() addrs.Resource

Addr returns a resource address for the receiver that is relative to the resource's containing module.

func (*Resource) HasCustomConditions

func (r *Resource) HasCustomConditions() bool

HasCustomConditions returns true if and only if the resource has at least one author-specified custom condition.

func (*Resource) ProviderConfigAddr

func (r *Resource) ProviderConfigAddr() addrs.LocalProviderConfig

ProviderConfigAddr returns the address for the provider configuration that should be used for this resource. This function returns a default provider config addr if an explicit "provider" argument was not provided.

type StateEncryption

type StateEncryption struct {
	Type   string
	Config hcl.Body

	TypeRange hcl.Range
	DeclRange hcl.Range
}

type TestCommand

type TestCommand rune

TestCommand represents the OpenTofu a given run block will execute, plan or apply. Defaults to apply.

type TestFile

type TestFile struct {
	// Variables defines a set of global variable definitions that should be set
	// for every run block within the test file.
	Variables map[string]hcl.Expression

	// Providers defines a set of providers that are available to run blocks
	// within this test file.
	//
	// If empty, tests should use the default providers for the module under
	// test.
	Providers map[string]*Provider

	// Runs defines the sequential list of run blocks that should be executed in
	// order.
	Runs []*TestRun

	VariablesDeclRange hcl.Range
}

TestFile represents a single test file within a `tofu test` execution.

A test file is made up of a sequential list of run blocks, each designating a command to execute and a series of validations to check after the command.

type TestFileModuleRequirements

type TestFileModuleRequirements struct {
	Requirements getproviders.Requirements
	Runs         map[string]*ModuleRequirements
}

TestFileModuleRequirements maps the runs for a given test file to the module requirements for that run block.

type TestMode

type TestMode rune

TestMode represents the plan mode that OpenTofu will use for a given run block, normal or refresh-only. Defaults to normal.

type TestRun

type TestRun struct {
	Name string

	// Command is the OpenTofu command to execute.
	//
	// One of ['apply', 'plan'].
	Command TestCommand

	// Options contains the embedded plan options that will affect the given
	// Command. These should map to the options documented here:
	//   - https://opentofu.org/docs/cli/commands/plan/#planning-options
	//
	// Note, that the Variables are a top level concept and not embedded within
	// the options despite being listed as plan options in the documentation.
	Options *TestRunOptions

	// Variables defines a set of variable definitions for this command.
	//
	// Any variables specified locally that clash with the global variables will
	// take precedence over the global definition.
	Variables map[string]hcl.Expression

	// Providers specifies the set of providers that should be loaded into the
	// module for this run block.
	//
	// Providers specified here must be configured in one of the provider blocks
	// for this file. If empty, the run block will load the default providers
	// for the module under test.
	Providers []PassedProviderConfig

	// CheckRules defines the list of assertions/validations that should be
	// checked by this run block.
	CheckRules []*CheckRule

	// Module defines an address of another module that should be loaded and
	// executed as part of this run block instead of the module under test.
	//
	// In the initial version of the testing framework we will only support
	// loading alternate modules from local directories or the registry.
	Module *TestRunModuleCall

	// ConfigUnderTest describes the configuration this run block should execute
	// against.
	//
	// In typical cases, this will be null and the config under test is the
	// configuration within the directory the tofu test command is
	// executing within. However, when Module is set the config under test is
	// whichever config is defined by Module. This field is then set during the
	// configuration load process and should be used when the test is executed.
	ConfigUnderTest *Config

	// ExpectFailures should be a list of checkable objects that are expected
	// to report a failure from their custom conditions as part of this test
	// run.
	ExpectFailures []hcl.Traversal

	NameDeclRange      hcl.Range
	VariablesDeclRange hcl.Range
	DeclRange          hcl.Range
}

TestRun represents a single run block within a test file.

Each run block represents a single OpenTofu command to be executed and a set of validations to run after the command.

func (*TestRun) Validate

func (run *TestRun) Validate() tfdiags.Diagnostics

Validate does a very simple and cursory check across the run block to look for simple issues we can highlight early on.

type TestRunModuleCall

type TestRunModuleCall struct {
	// Source is the source of the module to test.
	Source addrs.ModuleSource

	// Version is the version of the module to load from the registry.
	Version VersionConstraint

	DeclRange       hcl.Range
	SourceDeclRange hcl.Range
}

TestRunModuleCall specifies which module should be executed by a given run block.

type TestRunOptions

type TestRunOptions struct {
	// Mode is the planning mode to run in. One of ['normal', 'refresh-only'].
	Mode TestMode

	// Refresh is analogous to the -refresh=false OpenTofu plan option.
	Refresh bool

	// Replace is analogous to the -refresh=ADDRESS OpenTofu plan option.
	Replace []hcl.Traversal

	// Target is analogous to the -target=ADDRESS OpenTofu plan option.
	Target []hcl.Traversal

	DeclRange hcl.Range
}

TestRunOptions contains the plan options for a given run block.

type Variable

type Variable struct {
	Name        string
	Description string
	Default     cty.Value

	// Type is the concrete type of the variable value.
	Type cty.Type
	// ConstraintType is used for decoding and type conversions, and may
	// contain nested ObjectWithOptionalAttr types.
	ConstraintType cty.Type
	TypeDefaults   *typeexpr.Defaults

	ParsingMode VariableParsingMode
	Validations []*CheckRule
	Sensitive   bool

	DescriptionSet bool
	SensitiveSet   bool

	// Nullable indicates that null is a valid value for this variable. Setting
	// Nullable to false means that the module can expect this variable to
	// never be null.
	Nullable    bool
	NullableSet bool

	DeclRange hcl.Range
}

Variable represents a "variable" block in a module or file.

func (*Variable) Addr

func (v *Variable) Addr() addrs.InputVariable

func (*Variable) Required

func (v *Variable) Required() bool

Required returns true if this variable is required to be set by the caller, or false if there is a default value that will be used when it isn't set.

type VariableParsingMode

type VariableParsingMode rune

VariableParsingMode defines how values of a particular variable given by text-only mechanisms (command line arguments and environment variables) should be parsed to produce the final value.

const VariableParseHCL VariableParsingMode = 'H'

VariableParseHCL is a variable parsing mode that attempts to parse the given string as an HCL expression and returns the result.

const VariableParseLiteral VariableParsingMode = 'L'

VariableParseLiteral is a variable parsing mode that just takes the given string directly as a cty.String value.

func (VariableParsingMode) Parse

func (m VariableParsingMode) Parse(name, value string) (cty.Value, hcl.Diagnostics)

Parse uses the receiving parsing mode to process the given variable value string, returning the result along with any diagnostics.

A VariableParsingMode does not know the expected type of the corresponding variable, so it's the caller's responsibility to attempt to convert the result to the appropriate type and return to the user any diagnostics that conversion may produce.

The given name is used to create a synthetic filename in case any diagnostics must be generated about the given string value. This should be the name of the root module variable whose value will be populated from the given string.

If the returned diagnostics has errors, the returned value may not be valid.

type VariableTypeHint

type VariableTypeHint rune

VariableTypeHint is an enumeration used for the Variable.TypeHint field, which is an incompletely-specified type for the variable which is used as a hint for whether a value provided in an ambiguous context (on the command line or in an environment variable) should be taken literally as a string or parsed as an HCL expression to produce a data structure.

The type hint is applied to runtime values as well, but since it does not accurately describe a precise type it is not fully-sufficient to infer the dynamic type of a value passed through a variable.

These hints use inaccurate terminology for historical reasons. Full details are in the documentation for each constant in this enumeration, but in summary:

  • TypeHintString requires a primitive type
  • TypeHintList requires a type that could be converted to a tuple
  • TypeHintMap requires a type that could be converted to an object
const TypeHintList VariableTypeHint = 'L'

TypeHintList indicates that a value provided in an ambiguous context should be treated as an HCL expression, and additionally requires that the runtime value for the variable is of an tuple, list, or set type.

const TypeHintMap VariableTypeHint = 'M'

TypeHintMap indicates that a value provided in an ambiguous context should be treated as an HCL expression, and additionally requires that the runtime value for the variable is of an object or map type.

const TypeHintNone VariableTypeHint = 0

TypeHintNone indicates the absence of a type hint. Values specified in ambiguous contexts will be treated as literal strings, as if TypeHintString were selected, but no runtime value checks will be applied. This is reasonable type hint for a module that is never intended to be used at the top-level of a configuration, since descendent modules never receive values from ambiguous contexts.

const TypeHintString VariableTypeHint = 'S'

TypeHintString spec indicates that a value provided in an ambiguous context should be treated as a literal string, and additionally requires that the runtime value for the variable is of a primitive type (string, number, bool).

func (VariableTypeHint) String

func (i VariableTypeHint) String() string

type VersionConstraint

type VersionConstraint struct {
	Required  version.Constraints
	DeclRange hcl.Range
}

VersionConstraint represents a version constraint on some resource (e.g. OpenTofu Core, a provider, a module, ...) that carries with it a source range so that a helpful diagnostic can be printed in the event that a particular constraint does not match.

Directories

Path Synopsis
Package configload knows how to install modules into the .terraform/modules directory and to load modules from those installed locations.
Package configload knows how to install modules into the .terraform/modules directory and to load modules from those installed locations.
Package configschema contains types for describing the expected structure of a configuration block whose shape is not known until runtime.
Package configschema contains types for describing the expected structure of a configuration block whose shape is not known until runtime.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL