The tfconfig/v2
import provides access to a Terraform configuration.
The Terraform configuration is the set of *.tf
files that are used to describe the desired infrastructure state. Policies using the tfconfig
import can access all aspects of the configuration: providers, resources, data sources, modules, and variables.
Some use cases for tfconfig
include:
The data in the tfconfig/v2
import is sourced from the JSON configuration file that is generated by the terraform show -json
command. For more information on the file format, see the JSON Output Format page.
To configure the import, you must add the import to your configuration file and provide the path to the appropriate plan file.
import "plugin" "tfconfig/v2" {
config = {
"path": "./path/to/plan.json"
}
}
The tfconfig/v2
import is structured as a series of collections, keyed as a specific format, such as resource address, module address, or a specifically-formatted provider key.
tfconfig/v2
├── strip_index() (function)
├── providers
│ └── (indexed by [module_address:]provider[.alias])
│ ├── provider_config_key (string)
│ ├── name (string)
│ ├── full_name (string)
│ ├── alias (string)
│ ├── module_address (string)
│ ├── config (block expression representation)
│ └── version_constraint (string)
├── resources
│ └── (indexed by address)
│ ├── address (string)
│ ├── module_address (string)
│ ├── mode (string)
│ ├── type (string)
│ ├── name (string)
│ ├── provider_config_key (string)
│ ├── provisioners (list)
│ │ └── (ordered provisioners for this resource only)
│ ├── config (block expression representation)
│ ├── count (expression representation)
│ ├── for_each (expression representation)
│ └── depends_on (list of strings)
├── provisioners
│ └── (indexed by resource_address:index)
│ ├── resource_address (string)
│ ├── type (string)
│ ├── index (string)
│ └── config (block expression representation)
├── variables
│ └── (indexed by module_address:name)
│ ├── module_address (string)
│ ├── name (string)
│ ├── default (value)
│ └── description (string)
├── outputs
│ └── (indexed by module_address:name)
│ ├── module_address (string)
│ ├── name (string)
│ ├── sensitive (boolean)
│ ├── value (expression representation)
│ ├── description (string)
│ └── depends_on (list of strings)
└── module_calls
└── (indexed by module_address:name)
├── module_address (string)
├── name (string)
├── source (string)
├── config (block expression representation)
├── count (expression representation)
├── depends_on (expression representation)
├── for_each (expression representation)
└── version_constraint (string)
The collections are:
providers
- The configuration for all provider instances across all modules in the configuration.resources
- The configuration of all resources across all modules in the configuration.variables
- The configuration of all variable definitions across all modules in the configuration.outputs
- The configuration of all output definitions across all modules in the configuration.module_calls
- The configuration of all module calls (individual module
blocks) across all modules in the configuration.These collections are specifically designed to be used with the filter
quantifier expression in Sentinel, so that one can collect a list of resources to perform policy checks on without having to write complex module or configuration traversal. As an example, the following code will return all aws_instance
resource types within the configuration, regardless of what module they are in:
all_aws_instances = filter tfconfig.resources as _, r {
r.mode is "managed" and
r.type is "aws_instance"
}
You can add specific attributes to the filter to narrow the search, such as the module address. The following code would return resources in a module named foo
only:
all_aws_instances = filter tfconfig.resources as _, r {
r.module_address is "module.foo" and
r.mode is "managed" and
r.type is "aws_instance"
}
Address Differences Between tfconfig
, tfplan
, and tfstate
This import deals with configuration before it is expanded into a resource graph by Terraform. As such, it is not possible to compute an index as the import is building its collections and computing addresses for resources and modules.
As such, addresses found here may not always match the expanded addresses found in the tfplan/v2
and tfstate/v2
imports, specifically when count
and for_each
, are used.
As an example, consider a resource named null_resource.foo
with a count of 2
located in a module named bar
. While there will possibly be entries in the other imports for module.bar.null_resource.foo[0]
and module.bar.null_resource.foo[1]
, in tfconfig/v2
, there will only be a module.bar.null_resource.foo
. As mentioned in the start of this section, this is because configuration actually defines this scaling, whereas expansion actually happens when the resource graph is built, which happens as a natural part of the refresh and planning process.
The strip_index
helper function, found in this import, can assist in removing the indexes from addresses found in the tfplan/v2
and tfstate/v2
imports so that data from those imports can be used to reference data in this one.
The strip_index
helper function can be used to remove indexes from addresses found in tfplan/v2
and tfstate/v2
, by removing the indexes from each resource.
This can be used to help facilitate cross-import lookups for data between plan, state, and config.
import "tfconfig/v2" as tfconfig
import "tfplan/v2" as tfplan
main = rule {
all filter tfplan.resource_changes as _, rc {
rc.mode is "managed" and
rc.type is "aws_instance"
} as _, rc {
tfconfig.resources[tfconfig.strip_index(rc.address)].config.ami.constant_value is "ami-abcdefgh012345"
}
}
Most collections in this import will have one of two kinds of expression representations. This is a verbose format for expressing a (parsed) configuration value independent of the configuration source code, which is not 100% available to a policy check in HCP Terraform.
(expression representation)
├── constant_value (value)
└── references (list of strings)
There are two major parts to an expression representation:
constant_value
field.references
field. More details on this field can be found in the expression representation section of the JSON output format documentation.For example, to determine if an output is based on a particular resource value, one could do:
import "tfconfig/v2" as tfconfig
main = rule {
tfconfig.outputs["instance_id"].value.references is ["aws_instance.foo"]
}
Note: The representation does not account for complex interpolations or other expressions that combine constants with other expression data. For example, the partially constant data in "foo${var.bar}"
would be lost.
Expanding on the above, a multi-value expression representation (such as the kind found in a resources
collection element) is similar, but the root value is a keyed map of expression representations. This is repeated until a "scalar" expression value is encountered, ie: a field that is not a block in the resource's schema.
(block expression representation)
└── (attribute key)
├── (child block expression representation)
│ └── (...)
├── constant_value (value)
└── references (list of strings)
As an example, one can validate expressions in an aws_instance
resource using the following:
import "tfconfig/v2" as tfconfig
main = rule {
tfconfig.resources["aws_instance.foo"].config.ami.constant_value is "ami-abcdefgh012345"
}
Note that nested blocks, sometimes known as sub-resources, will be nested in configuration as as list of blocks (reflecting their ultimate nature as a list of objects). An example would be the aws_instance
resource's ebs_block_device
block:
import "tfconfig/v2" as tfconfig
main = rule {
tfconfig.resources["aws_instance.foo"].config.ebs_block_device[0].volume_size < 10
}
The providers
collection is a collection representing the configurations of all provider instances across all modules in the configuration.
This collection is indexed by an opaque key. This is currently module_address:provider.alias
, the same value as found in the provider_config_key
field. module_address
and the colon delimiter are omitted for the root module.
The provider_config_key
field is also found in the resources
collection and can be used to locate a provider that belongs to a configured resource.
The fields in this collection are as follows:
provider_config_key
- The opaque configuration key, used as the index key.name
- The name of the provider, ie: aws
.full_name
- The fully-qualified name of the provider, e.g. registry.terraform.io/hashicorp/aws
.alias
- The alias of the provider, ie: east
. Empty for a default provider.module_address
- The address of the module this provider appears in.config
- A block expression representation with provider configuration values.version_constraint
- The defined version constraint for this provider.The resources
collection is a collection representing all of the resources found in all modules in the configuration.
This collection is indexed by the resource address.
The fields in this collection are as follows:
address
- The resource address. This is the index of the collection.module_address
- The module address that this resource was found in.mode
- The resource mode, either managed
(resources) or data
(data sources).type
- The type of resource, ie: null_resource
in null_resource.foo
.name
- The name of the resource, ie: foo
in null_resource.foo
.provider_config_key
- The opaque configuration key that serves as the index of the providers
collection.provisioners
- The ordered list of provisioners for this resource. The syntax of the provisioners matches those found in the provisioners
collection, but is a list indexed by the order the provisioners show up in the resource.config
- The block expression representation of the configuration values found in the resource.count
- The expression data for the count
value in the resource.for_each
- The expression data for the for_each
value in the resource.depends_on
- The contents of the depends_on
config directive, which declares explicit dependencies for this resource.The provisioners
collection is a collection of all of the provisioners found across all resources in the configuration.
While normally bound to a resource in an ordered fashion, this collection allows for the filtering of provisioners within a single expression.
This collection is indexed with a key following the format resource_address:index
, with each field matching their respective field in the particular element below:
resource_address
: The address of the resource that the provisioner was found in. This can be found in the resources
collection.type
: The provisioner type, ie: local_exec
.index
: The provisioner index as it shows up in the resource provisioner order.config
: The block expression representation of the configuration values in the provisioner.The variables
collection is a collection of all variables across all modules in the configuration.
Note that this tracks variable definitions, not values. See the tfplan/v2
variables
collection for variable values set within a plan.
This collection is indexed by the key format module_address:name
, with each field matching their respective name below. module_address
and the colon delimiter are omitted for the root module.
module_address
- The address of the module the variable was found in.name
- The name of the variable.default
- The defined default value of the variable.description
- The description of the variable.The outputs
collection is a collection of all outputs across all modules in the configuration.
Note that this tracks variable definitions, not values. See the tfstate/v2
outputs
collection for the final values of outputs set within a state. The tfplan/v2
output_changes
collection also contains a more complex collection of planned output changes.
This collection is indexed by the key format module_address:name
, with each field matching their respective name below. module_address
and the colon delimiter are omitted for the root module.
module_address
- The address of the module the output was found in.name
- The name of the output.sensitive
- Indicates whether or not the output was marked as sensitive
.value
- An expression representation for the output.description
- The description of the output.depends_on
- A list of resource names that the output depends on. These are the hard-defined output dependencies as defined in the depends_on
field in an output declaration, not the dependencies that get derived from natural evaluation of the output expression (these can be found in the references
field of the expression representation).The module_calls
collection is a collection of all module declarations at all levels within the configuration.
Note that this is the module
stanza in any particular configuration, and not the module itself. Hence, a declaration for module.foo
would actually be declared in the root module, which would be represented by a blank field in module_address
.
This collection is indexed by the key format module_address:name
, with each field matching their respective name below. module_address
and the colon delimiter are omitted for the root module.
module_address
- The address of the module the declaration was found in.name
- The name of the module.source
- The contents of the source
field.config
- A block expression representation for all parameter values sent to the module.count
- An expression representation for the count
field.depends_on
: An expression representation for the depends_on
field.for_each
- An expression representation for the for_each
field.version_constraint
- The string value found in the version
field of the module declaration.RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4