Terraform
component block reference
Use the component block to source the individual modules that make up your Stack. You can define component blocks in a <NAME>.tfcomponent.hcl file, which is a component configuration file for your Stack. Each component represents a reusable piece of infrastructure that you can provision and manage.
Background
The component block defines the infrastructure to include in your Stack. Each Stack requires at least one component block, and you must add a component block to your configuration for every module you want to include in your Stack.
Each component sources a Terraform module, can receive input variables, and accepts providers that you declare at the Stack level. You can define the following configuration blocks in a tfcomponent.hcl file:
- Use the
required_providersblock to declare which providers your component configuration requires so that Terraform can install and use them. - Use the
providerblock to configure providers, then pass that configuration to a component. - Use the
removedblock to define the components you want to remove from your Stack. - Use the
variableblock to define input variables for a Stack. - Use the
outputblock to define outputs that you want to refer to in the HCP Terraform UI. - Use the
localsblock to define local values that you can use within your component configuration.
Configuration model
The component block supports the following arguments:
component "<LABEL>"Â block
Complete configuration
All available arguments are defined in the following component block. The source, inputs, and providers arguments are required.
component "<LABEL>" {
for_each = <MAP_OR_SET>
source = "<MODULE_SOURCE>"
version = "<VERSION_CONSTRAINT>"
inputs = {
<VAR_NAME> = <VALUE>
}
providers = {
<PROVIDER_NAME> = provider.<PROVIDER_TYPE>.<ALIAS>
}
depends_on = [component.<COMPONENT_NAME>]
}
Specification
A component block supports the following configuration.
component "<LABEL>"
The label after the component keyword is a name for the component, which must be unique among all components in the same component configuration. The name of a component can be any valid identifier.
The following arguments are supported in a component block:
| Argument | Description | Type | Required? |
|---|---|---|---|
source | The Terraform module to source for this component. | String | Required |
version | The module version to use when sourcing from the public Terraform registry. | String | Optional |
inputs | A mapping of module input variable names to values. | Map | Required |
providers | A mapping of provider names to providers declared in your component configuration. | Map | Required |
depends_on | A list of other components that HCP Terraform must execute before this component. | List | Optional |
for_each | Creates multiple instances of the component based on a map or set of values. | Map or Set | Optional |
source
The source argument specifies the Terraform module to use for this component. You can reference modules from various sources, including local paths, Git repositories, the Terraform registry, and the HCP Terraform private registry.
component "<LABEL>" {
source = "<NAMESPACE>/<NAME>/<PROVIDER>"
# ...
}
The source argument accepts the same module sources as the module block in traditional Terraform configurations.
Summary
- Data type: String
- Default: None
- Required: Yes
version
Use the version argument to specify which version of a module to use when sourcing from the public Terraform registry or private HCP Terraform registry.
component "<LABEL>" {
source = "<NAMESPACE>/<NAME>/<PROVIDER>"
version = "<VERSION_CONSTRAINT>"
# ...
}
The version argument accepts a version constraint string. Terraform uses the newest installed version of the module that meets the constraint. When an acceptable version isn't installed, Terraform downloads the newest version that meets the constraint. We recommend explicitly constraining the acceptable version numbers to avoid unexpected or unwanted changes.
If you plan to validate your configuration locally, run terraform stacks init after modifying the version argument so that Terraform can update the local cache.
You can only use the version argument when the source argument points to a module listed in a registry, such as the public Terraform Registry
or HCP Terraform's private module registry. Modules sourced from local file paths do not support version because they're loaded from the same source repository and always share the same version as their caller.
Summary
- Data type: String
- Default: None
providers
The providers argument defines a mapping of provider names to providers declared in your component configuration. Modules cannot configure their own providers in component configurations, so you must declare providers at the Stack level and pass them to each component.
component "storage" {
source = "./modules/s3"
providers = {
PROVIDER_NAME_IN_MODULE = "provider.<PROVIDER_NAME>.<PROVIDER_ALIAS>"
}
# ...
}
The keys in the providers map must match the provider names that the source module expects, and the values must reference providers declared in your component configuration. Learn more about Declaring providers in Stacks.
Summary
- Data type: Map
- Default: None
- Required: Yes
inputs
The inputs argument defines a mapping of module input variable names to values. The keys of this map must correspond to the variable names defined by the source module.
component "database" {
source = "./modules/database"
providers = {
random = provider.random.this
}
inputs = {
VAR_NAME = "<VALUE>"
}
}
You can use three types of values in the inputs map:
- Variable references, such as
var.variable_name. - Component outputs, such as
component.component_name.output_name. - Literal values, such as primitives and functions.
Summary
- Data type: Object
- Default: None
- Required: Yes
depends_on
The depends_on argument specifies explicit dependencies on other components. HCP Terraform executes components in the depends_on list before executing the current component.
component "app_server" {
depends_on = [
component.<COMPONENT_NAME>
]
# ...
}
You do not need to include the dependant component’s outputs in the depends_on list because Terraform automatically recognizes those dependencies.
Summary
- Data type: List of references
- Default: None
for_each
The for_each argument creates multiple instances of a component based on a map or set of values. This meta-argument lets you provision the same infrastructure pattern across multiple environments, regions, or configurations.
component "<LABEL>" {
for_each = [ "<VALUE>" ]
# . . .
}
When you use for_each, Terraform creates one component instance for each item in the collection. You can reference individual instances using component.<LABEL>[<KEY>] syntax.
Summary
- Data type: Map or Set
- Default: None
Examples
The following examples demonstrate common use cases for component blocks.
Source a local module
In the following example, Terraform sources the web_server module from the modules/web_server directory within the current component configuration to create a web component:
component "web" {
source = "./modules/web_server"
inputs = {
instance_type = "t3.micro"
subnet_id = "subnet-12345678"
}
providers = {
aws = provider.aws.main
}
}
As part of configuring the web component, you must define the provider configuration and input the variable values that the web_server module requires.
Source a module from the Terraform registry
In the following example, Terraform sources the vpc component from the terraform-aws-modules/vpc/aws module in the public Terraform registry and constrains it to version 5.x:
component "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
inputs = {
name = "main-vpc"
cidr = "10.0.0.0/16"
azs = ["us-west-2a", "us-west-2b"]
}
providers = {
aws = provider.aws.main
}
}
As part of configuring the vpc component, define the provider configuration and input the variable values that the terraform-aws-modules/vpc/aws module requires.
Component with dependencies
In the following example, the app_server component references outputs from the database component and declares an explicit dependency on that component to Terraform creates the components in the proper order:
component "app_server" {
source = "./modules/app-server"
inputs = {
name = "main-vpc"
cidr = "10.0.0.0/16"
azs = ["us-west-2a", "us-west-2b"]
}
providers = {
aws = provider.aws.main
}
depends_on = [
component.database
]
}
Multiple component instances
In the following example, Terraform creates three storage components, one for each region specified in the set, with each component receiving region-specific configuration:
component "regional_storage" {
for_each = toset(["us-east-1", "us-west-2", "eu-west-1"])
source = "./modules/storage"
inputs = {
region = each.value
bucket_name = "app-data-${each.value}"
}
providers = {
aws = provider.aws.configurations[each.value]
}
}
To learn more about breaking down your infrastructure into components, refer to Define component configuration.