--- page_title: Upgrading to Terraform v1.6 description: Upgrading to Terraform v1.6 --- # Upgrading to Terraform v1.6 -> **Tip:** Use the version selector to view the upgrade guides for older Terraform versions. Terraform v1.6 is a minor release in the stable Terraform v1.0 series. Terraform v1.6 honors the [Terraform v1.0 Compatibility Promises](https://developer.hashicorp.com/terraform/language/v1-compatibility-promises), but there are some behavior changes outside of those promises that may affect a small number of users. Specifically, the following updates may require additional upgrade steps: * [End of experimental period for `terraform test`](#terraform-test) * [Deprecated parameters for the S3 backend](#s3-backend) See [the full changelog](https://github.com/hashicorp/terraform/blob/v1.6/CHANGELOG.md) for more details. If you encounter any problems during upgrading which are not covered this guide, please start a new topic in [the Terraform community forum](https://discuss.hashicorp.com/c/terraform-core) to discuss it. ## Terraform Test The previous experimental `terraform test` command has been deprecated and replaced with a fully supported and finalized `terraform test` command. There are substantial differences between the previous experimental approach and the finalized approach: - The builtin test provider, `terraform.io/builtin/test`, has been removed and a dedicated syntax introduced for testing files. - A new `.tftest.hcl` file extension has been introduced for testing files, allowing a change into the directory structure and test file layout. - Test assertions and conditions execute with extended scope and access to the configuration under test. The major differences are discussed here, for more information consult the [CLI](/terraform/cli/test) and [Language](/terraform/language/tests) documentation. ### Directory structure Previously, test files would be placed within their own subdirectories underneath the `tests` directory from the configuration directory. The following example contains three test files using the experimental framework: ``` main.tf outputs.tf providers.tf variables.tf tests/ defaults/ test_defaults.tf maximums/ test_maximums.tf minimums/ test_minimums.tf ``` With the new directory structure, tests are defined using the new `.tftest.hcl` file extension and do not need to be embedded within subdirectories. To help with organization, test files can, optionally, be embedded within a test directory. The name for this test directory defaults to `tests`, but can be overridden with the `-test-directory` flag. The following examples are both valid directory structures for test files in the updated framework: ``` main.tf outputs.tf providers.tf variables.tf defaults.tftest.hcl maximums.tftest.hcl minimums.tftest.hcl ``` ``` main.tf outputs.tf providers.tf variables.tf tests/ defaults.tftest.hcl maximums.tftest.hcl minimums.tftest.hcl ``` ### Test structure and assertions Previously, a test file would contain a module call and a collection of resources from the builtin `test` provider: ```hcl # tests/defaults/test_defaults.tf terraform{ required_providers { test = { source = "terraform.io/builtin/test" } } } module "main" { source = "../.." } resource "test_assertions" "api_url" { component = "api_url" equal "scheme" { description = "default scheme is https" got = module.main.scheme want = "https" } check "port_number" { description = "default port number is 8080" condition = can(regex(":8080$", module.main.authority)) } } ``` With the new framework each test file is made up of a series of `run` blocks. Each `run` block represents a single `terraform plan` or a `terraform apply` operation executed against the main configuration. Assertions from within these `run` blocks can access outputs, variables, resources, and local values from the main configuration directly. ```hcl # tests/defaults.tftest.hcl run "test_defaults" { assert { condition = output.scheme == "https" error_message = "default scheme should be https" } assert { condition = can(regex(":8080", output.authority)) error_message = "default port number should be 8080" } } ``` The above examples demonstrates the differences in layout, scope and access between the two approaches. In the experimental framework, access is granted as if the configuration was being called like a normal module call. In the released framework, assertions execute as if they are custom conditions defined within the main configuration directly. The `run` block also applies or plans the main configuration by default, there is no need for the specific module call seen in the experimental framework. ## S3 Backend We updated the S3 backend in Terraform 1.6.0 so that it more closely matches the AWS provider configuration. As a result, the backend has new and deprecated fields. Refer to the [release notes](https://github.com/hashicorp/terraform/releases/tag/v1.6.0) for additional information. The major deprecations are discussed here. Refer to the [S3 backend documentation](/terraform/language/settings/backends/s3) for information about all deprecations. We removed the configuration for assuming an IAM role from several top-level attributes and consolidated them into the `assume_role` attribute. The following example shows the configuration in Terraform 1.5.6 and older for assuming the IAM role `arn:aws:iam::123456789012:role/example` with a session name `example-session` and a session duration of 15 minutes: ```hcl terraform { backend "s3" { # additional configuration omitted for brevity role_arn = "arn:aws:iam::123456789012:role/example" session_name = "example-session" assume_role_duration_seconds = 900 } } ``` The configuration in Terraform 1.6.0 is: ```hcl terraform { backend "s3" { # additional configuration omitted for brevity assume_role = { role_arn = "arn:aws:iam::123456789012:role/example" session_name = "example-session" duration = "15m" } } } ``` We removed the configuration for overriding AWS API endpoints from several top-level attributes and consolidated them into the `endpoints` attribute. The following endpoint attributes are now nested under the `endpoint` attribute: - `s3` - `dynamodb` - `iam` - `sts` The `endpoint` attribute replaces the following top-level attributes: - `endpoint` (for S3), - `dynamodb_endpoint`, - `iam_endpoint` - `sts_endpoint`