Skip to content

remote_state

unit

Usage

The remote_state block configures the backend that stores a unit’s state, so you can set it once in a file every unit includes. See State backend.

Terragrunt passes the config map to the OpenTofu/Terraform backend block:

terragrunt.hcl
remote_state {
backend = "s3"
config = {
bucket = "mybucket"
key = "path/to/my/key"
region = "us-east-1"
}
}
Equivalent OpenTofu/Terraform
terraform {
backend "s3" {
bucket = "mybucket"
key = "path/to/my/key"
region = "us-east-1"
}
}

Without generate, the module needs an empty backend block of the same type, e.g. terraform { backend "s3" {} }, for Terragrunt to fill in.

Setting remote_state as an attribute

remote_state also works as an attribute, so a unit can set it from another file:

terragrunt.hcl
locals {
common = read_terragrunt_config(find_in_parent_folders("common.hcl"))
}
remote_state = local.common.remote_state

Backend bootstrapping

With --backend-bootstrap, or with terragrunt backend bootstrap, Terragrunt creates the backend’s storage before init if it’s missing, e.g. an S3 bucket, and checks its configuration if it exists. It can do that for the s3, gcs, and azurerm backends.

Otherwise, Terragrunt leaves the storage alone, and init fails if the storage doesn’t exist. disable_init = true makes Terragrunt leave it alone even with --backend-bootstrap.

Encrypting state

The encryption map needs a key_provider key, set to any key provider OpenTofu supports, e.g. pbkdf2, aws_kms, gcp_kms, or openbao. Its other keys configure that provider. Terragrunt turns the map into an encryption block in the OpenTofu terraform block:

terragrunt.hcl
remote_state {
backend = "s3"
config = {
bucket = "mybucket"
key = "path/to/my/key"
region = "us-east-1"
}
encryption = {
key_provider = "pbkdf2"
passphrase = get_env("PBKDF2_PASSPHRASE")
}
}
Generated OpenTofu
terraform {
backend "s3" {
bucket = "mybucket"
key = "path/to/my/key"
region = "us-east-1"
}
encryption {
key_provider "pbkdf2" "default" {
passphrase = "SUPERSECRETPASSPHRASE"
}
method "aes_gcm" "default" {
keys = key_provider.pbkdf2.default
}
state {
method = method.aes_gcm.default
}
plan {
method = method.aes_gcm.default
}
}
}

Two keys in the encryption map go to the generated state and plan blocks instead of the key provider:

  • fallback: Set to { method = "unencrypted" } to let OpenTofu read state and plan files written before encryption was enabled. Any other value is an error.
  • enforced: Set to true to make OpenTofu error instead of writing unencrypted state or plan files.

Once encryption is configured, OpenTofu refuses to read plaintext state. A unit with existing state therefore needs the fallback for one run, as described under pre-existing project in the OpenTofu docs:

terragrunt.hcl
remote_state {
backend = "s3"
config = {
bucket = "mybucket"
key = "path/to/my/key"
region = "us-east-1"
}
encryption = {
key_provider = "pbkdf2"
passphrase = get_env("PBKDF2_PASSPHRASE")
fallback = { method = "unencrypted" }
}
}

Terragrunt adds an unencrypted method and points both blocks at it:

backend.tf
encryption {
# key_provider and method "aes_gcm" as above
method "unencrypted" "fallback" {
}
state {
method = method.aes_gcm.default
fallback {
method = method.unencrypted.fallback
}
}
plan {
method = method.aes_gcm.default
fallback {
method = method.unencrypted.fallback
}
}
}

Run terragrunt apply so OpenTofu writes the state back encrypted. Then replace fallback with enforced = true.

Examples

Stores state in the S3 bucket my-tofu-state, with a key per unit, e.g. child/tofu.tfstate for a unit in child. Terragrunt can create the bucket and the DynamoDB lock table.

root.hcl
remote_state {
backend = "s3"
config = {
bucket = "my-tofu-state"
key = "${path_relative_to_include()}/tofu.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "my-lock-table"
}
}

Stores state in the GCS bucket my-tofu-state, and labels the bucket if Terragrunt creates it.

root.hcl
remote_state {
backend = "gcs"
config = {
project = "my-tofu"
location = "eu"
bucket = "my-tofu-state"
prefix = path_relative_to_include()
gcs_bucket_labels = {
owner = "terragrunt_test"
name = "tofu_state_storage"
}
}
}

Stores state in the tfstate container of the Azure storage account mytofustate. Reading and writing state with use_azuread_auth needs the Storage Blob Data Contributor role on the account. Set assign_blob_data_role = true to have bootstrapping grant it.

root.hcl
remote_state {
backend = "azurerm"
config = {
resource_group_name = "my-tofu-state"
storage_account_name = "mytofustate"
container_name = "tfstate"
key = "${path_relative_to_include()}/tofu.tfstate"
location = "eastus"
use_azuread_auth = true
}
}

Locks state with S3 native locking instead of DynamoDB. It needs OpenTofu 1.10 or later.

root.hcl
remote_state {
backend = "s3"
config = {
bucket = "my-tofu-state"
key = "${path_relative_to_include()}/tofu.tfstate"
region = "us-east-1"
encrypt = true
use_lockfile = true
}
}

Takes both locks while you migrate from DynamoDB to S3 native locking. Once the migration is done, remove dynamodb_table. Terragrunt doesn’t delete the table.

root.hcl
remote_state {
backend = "s3"
config = {
bucket = "my-tofu-state"
key = "${path_relative_to_include()}/tofu.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "my-lock-table"
use_lockfile = true
}
}

Attributes

backendstring

The backend to store state in, e.g. s3, gcs, or azurerm.

terragrunt.hcl
remote_state {
backend = "s3"
config = {
bucket = "my-tofu-state"
key = "vpc/tofu.tfstate"
region = "us-east-1"
}
}
configmap(any)

The backend’s configuration. Terragrunt passes it to the OpenTofu/Terraform backend block, except for the keys Terragrunt uses to create the backend’s storage. See Backend config keys.

terragrunt.hcl
remote_state {
backend = "s3"
config = {
bucket = "my-tofu-state"
key = "${path_relative_to_include()}/tofu.tfstate"
region = "us-east-1"
encrypt = true
use_lockfile = true
}
}
generateoptional(object({path = string, if_exists = string}))

Writes the backend configuration to a .tf file, so the module needs no backend block of its own. path is the file to write, relative to the directory Terragrunt runs OpenTofu/Terraform in. if_exists sets what happens when the file exists: overwrite, overwrite_terragrunt to overwrite only a file Terragrunt generated and fail otherwise, skip, or error.

terragrunt.hcl
remote_state {
backend = "s3"
config = {
bucket = "my-tofu-state"
key = "vpc/tofu.tfstate"
region = "us-east-1"
}
generate = {
path = "backend.tf"
if_exists = "overwrite_terragrunt"
}
}
disable_initoptional(bool, false)

Stops Terragrunt from creating or updating the backend’s storage, e.g. an S3 bucket. OpenTofu/Terraform still initializes the backend, and generate still writes the backend configuration. Terragrunt can create storage for the s3, gcs, and azurerm backends. See Backend bootstrapping.

terragrunt.hcl
remote_state {
backend = "s3"
config = {
bucket = "my-tofu-state"
key = "vpc/tofu.tfstate"
region = "us-east-1"
}
disable_init = true
}
disable_dependency_optimizationoptional(bool, false)

Turns off Terragrunt’s optimized fetching of dependency outputs for units with this remote_state block.

terragrunt.hcl
remote_state {
backend = "s3"
config = {
bucket = "my-tofu-state"
key = "vpc/tofu.tfstate"
region = "us-east-1"
}
disable_dependency_optimization = true
}
encryptionoptional(map(any))

State and plan encryption for OpenTofu. Its key_provider key names an OpenTofu key provider, and the other keys configure it. See Encrypting state.

terragrunt.hcl
remote_state {
backend = "s3"
config = {
bucket = "my-tofu-state"
key = "vpc/tofu.tfstate"
region = "us-east-1"
}
encryption = {
key_provider = "pbkdf2"
passphrase = get_env("PBKDF2_PASSPHRASE")
}
}

Backend config keys

For the s3, gcs, and azurerm backends, Terragrunt reads these config keys to provision the backend’s storage. It passes every key on to the OpenTofu/Terraform backend except the ones used only for provisioning.

Used by Terragrunt for backend provisioning

S3backend = "s3"
bucketstring

The S3 bucket that stores state. Terragrunt creates it when it bootstraps the backend.

keystring

The path of the state file in the bucket.

regionstring

The bucket’s AWS region.

profileoptional(string)

The AWS profile name, as set in the shared credentials file.

shared_credentials_fileoptional(string)

The path to the shared credentials file. With a profile and no file, Terragrunt uses ~/.aws/credentials.

role_arnoptional(string)

The role to assume. assume_role.role_arn takes precedence.

external_idoptional(string)

The external ID to use when assuming the role. assume_role.external_id takes precedence.

session_nameoptional(string)

The session name to use when assuming the role. assume_role.session_name takes precedence.

assume_roleoptional(object)

Settings for assuming a role, for Terraform 1.6 or later.

role_arnstring

The role to assume.

durationoptional(string)

How long the credentials are valid.

external_idoptional(string)

The external ID to use when assuming the role.

policyoptional(string)

A JSON policy that further restricts the role.

policy_arnsoptional(list(string))

Policy ARNs that further restrict the role.

session_nameoptional(string)

The session name to use when assuming the role.

source_identityoptional(string)

The source identity to use when assuming the role.

tagsoptional(map(string))

Session tags for the assumed role.

transitive_tag_keysoptional(list(string))

Tag keys to pass on to later sessions.

assume_role_with_web_identityoptional(object)

Settings for assuming a role with a web identity token. Terragrunt passes them on to OpenTofu/Terraform and doesn’t use them itself.

role_arnstring

The role to assume.

durationoptional(string)

How long the credentials are valid.

policyoptional(string)

A JSON policy that further restricts the role.

policy_arnsoptional(list(string))

Policy ARNs that further restrict the role.

session_nameoptional(string)

The session name to use when assuming the role.

web_identity_tokenoptional(string)

The web identity token. Set this or web_identity_token_file.

web_identity_token_fileoptional(string)

The path to a file holding the web identity token.

endpointoptional(string)

A custom endpoint for the S3 API. OpenTofu deprecates it in favor of endpoints.s3.

dynamodb_endpointoptional(string)

A custom endpoint for the DynamoDB API. OpenTofu deprecates it in favor of endpoints.dynamodb.

endpointsoptional(object)

Custom service endpoints, for Terraform 1.6 or later. They take precedence over endpoint and dynamodb_endpoint.

s3optional(string)

A custom endpoint for the S3 API. Set this or endpoint, because OpenTofu rejects both together.

dynamodboptional(string)

A custom endpoint for the DynamoDB API. Set this or dynamodb_endpoint, because OpenTofu rejects both together.

force_path_styleoptional(bool, false)

Addresses the bucket with path-style URLs, which most S3-compatible object stores need. OpenTofu deprecates it in favor of use_path_style.

use_path_styleoptional(bool, false)

The newer name for force_path_style. Set this or force_path_style, because OpenTofu rejects both together.

encryptoptional(bool, false)

Enables server-side encryption of the state file. When it’s off, Terragrunt logs a warning, or a debug message if skip_bucket_ssencryption is set.

dynamodb_tableoptional(string)

A DynamoDB table for state locking, with a primary key named LockID. Terragrunt creates it when it bootstraps the backend. Without it, DynamoDB locking is off.

lock_tabledeprecatedoptional(string)

The old name for dynamodb_table. Terragrunt logs a warning and uses it as dynamodb_table.

use_lockfileoptional(bool, false)

Locks state with S3 conditional writes. It needs OpenTofu 1.10 or later. It can run with dynamodb_table during a migration, when both locks must succeed.

skip_credentials_validationoptional(bool, false)

Skips Terragrunt’s check that the AWS credentials are valid.

skip_bucket_versioningUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Skips enabling versioning on the bucket Terragrunt creates.

skip_bucket_ssencryptionUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Skips configuring server-side encryption on the bucket Terragrunt creates.

skip_bucket_enforced_tlsUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Skips adding a bucket policy that requires TLS.

skip_bucket_public_access_blockingUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Skips blocking public access to the bucket.

enable_bucket_root_accessUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Adds a bucket policy statement granting s3:* on the bucket and its objects to arn:aws:iam::<account-id>:root. Despite its name, that ARN grants access to the whole AWS account, not only its root user. Terragrunt adds the statement to existing buckets as well as ones it creates.

disable_bucket_updateUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Stops Terragrunt from updating an existing bucket to match the configuration.

bucket_sse_algorithmUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(string, "aws:kms")

The server-side encryption algorithm for the bucket.

bucket_sse_kms_key_idUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(string)

The KMS key for aws:kms encryption. Defaults to the AWS managed aws/s3 key.

s3_bucket_tagsUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(map(string))

Tags for the bucket Terragrunt creates.

enable_lock_table_ssencryptionUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Enables server-side encryption on the DynamoDB lock table.

dynamodb_table_tagsUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(map(string))

Tags for the DynamoDB lock table Terragrunt creates.

disable_aws_client_checksumsUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Turns off request and response checksums, such as the CRC32 check for DynamoDB. See #1059 for when this helps.

accesslogging_bucket_nameUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(string)

A bucket for the state bucket’s access logs, which Terragrunt creates. Without a valid bucket name, access logging is off. With access logging on, the state bucket supports only AES256 encryption. See S3 server access logging.

accesslogging_target_prefixUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(string, "…")

The prefix for access log objects. An empty string sets an empty prefix. It needs accesslogging_bucket_name.

accesslogging_target_object_partition_date_sourceUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(string)

The PartitionDateSource of the access log object key format. See Logging requests with server access logging.

accesslogging_bucket_tagsUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(map(string))

Tags for the access log bucket Terragrunt creates.

skip_accesslogging_bucket_policyUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Skips the bucket policy that lets S3 deliver access logs to the access log bucket.

skip_accesslogging_bucket_enforced_tlsUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Skips adding a policy that requires TLS to the access log bucket.

skip_accesslogging_bucket_public_access_blockingUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Skips blocking public access to the access log bucket.

skip_accesslogging_bucket_ssencryptionUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Skips configuring server-side encryption on the access log bucket.

skip_bucket_accessloggingUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningdeprecatedoptional(bool)

Ignored. Terragrunt logs a warning.

skip_bucket_root_accessUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningdeprecatedoptional(bool)

Ignored. Terragrunt logs a warning when it bootstraps the backend. The skip-bucket-root-access strict control turns the warning into an error.

skip_accesslogging_bucket_aclUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningdeprecatedoptional(bool)

Has no effect, since Terragrunt sets no ACL. Use skip_accesslogging_bucket_policy to skip the grant. Terragrunt logs a warning. See the skip-accesslogging-bucket-acl strict control.

GCSbackend = "gcs"
bucketstring

The GCS bucket that stores state. Terragrunt creates it when it bootstraps the backend.

credentialsoptional(string)

The local path to a GCP service account credentials file in JSON format. Terragrunt takes only a path here.

access_tokenoptional(string)

A temporary OAuth 2.0 access token.

impersonate_service_accountoptional(string)

A service account to impersonate. Terragrunt creates and checks the bucket as this account.

impersonate_service_account_delegatesoptional(list(string))

The delegation chain for impersonating impersonate_service_account.

projectUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(string)

The GCP project to create the bucket in.

locationUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(string)

The GCP location to create the bucket in.

gcs_bucket_labelsUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(map(string))

Labels for the bucket Terragrunt creates.

skip_bucket_creationUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Stops Terragrunt from creating the bucket.

skip_bucket_versioningUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Skips enabling versioning on the bucket Terragrunt creates.

enable_bucket_policy_onlyUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Gives the bucket Terragrunt creates uniform bucket-level access.

See GCS backend for the authentication order and known limitations.

Azure Storagebackend = "azurerm"

Terragrunt also reads the backend’s authentication keys, e.g. use_azuread_auth, client_id, or sas_token, and passes them on.

storage_account_namestring

The storage account that stores state.

container_namestring

The blob container that stores state.

keystring

The name of the state blob in the container.

resource_group_nameoptional(string)

The resource group of the storage account. Terragrunt needs it to create or inspect the account, but not to authenticate with a SAS token or an access key.

locationUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(string)

The Azure region for the resource group and storage account, e.g. eastus. Required when Terragrunt creates them.

account_kindUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(string, "StorageV2")

The storage account kind.

account_tierUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(string, "Standard")

The storage account tier, Standard or Premium.

account_replication_typeUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(string, "LRS")

The replication type, e.g. LRS, GRS, or ZRS.

access_tierUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(string, "Hot")

The blob access tier, Hot, Cool, Cold, or Premium.

minimum_tls_versionUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(string, "TLS1_2")

The minimum TLS version for requests to the storage account, TLS1_2 or TLS1_3. It applies only when Terragrunt creates the account.

tagsUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(map(string))

Tags for the storage account Terragrunt creates.

skip_resource_group_creationUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Stops Terragrunt from creating the resource group.

skip_storage_account_creationUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Stops Terragrunt from creating the storage account, so it must exist.

skip_container_creationUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Stops Terragrunt from creating the blob container, so it must exist.

skip_versioningUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Skips enabling blob versioning on the account.

enable_soft_deleteUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Enables blob and container soft delete.

soft_delete_retention_daysUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(number, 7)

The soft delete retention in days, from 1 to 365.

allow_blob_public_accessUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Lets containers on the account allow anonymous access.

assign_blob_data_roleUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(bool, false)

Makes bootstrapping grant Storage Blob Data Contributor on the storage account to principal_id, or to the identity Terragrunt authenticated as when it’s unset. It needs permission to create role assignments.

principal_idUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(string)

The Microsoft Entra object ID that receives the data-plane role when assign_blob_data_role is true.

msi_resource_idUsed by Terragrunt for backend provisioningUsed by Terragrunt for backend provisioningoptional(string)

The resource ID of a user-assigned managed identity to use with use_msi.

For a premium account that stores state as block blobs, set account_kind = "BlockBlobStorage", account_tier = "Premium", and access_tier = "Premium", with LRS or ZRS replication. Setting only account_tier = "Premium" keeps the StorageV2 and Hot defaults, which don’t form a valid block blob account.

See Azure Storage backend for the authentication order and known limitations.