diff --git a/website/data/language-nav-data.json b/website/data/language-nav-data.json
index 22f3999d28..fe3c4d8d21 100644
--- a/website/data/language-nav-data.json
+++ b/website/data/language-nav-data.json
@@ -213,11 +213,6 @@
"path": "modules/develop/refactoring"
}
]
- },
- {
- "title": "Module Testing Experiment",
- "path": "modules/testing-experiment",
- "hidden": true
}
]
},
diff --git a/website/docs/cli/cloud/index.mdx b/website/docs/cli/cloud/index.mdx
index 4a8212c077..51136e4cd1 100644
--- a/website/docs/cli/cloud/index.mdx
+++ b/website/docs/cli/cloud/index.mdx
@@ -1,5 +1,7 @@
---
page_title: Using Terraform Cloud - Terraform CLI
+description: >-
+ Learn how to use Terraform Cloud and Terraform Enterprise on the command line with the Terraform CLI.
---
# Using Terraform Cloud with Terraform CLI
diff --git a/website/docs/cli/cloud/migrating.mdx b/website/docs/cli/cloud/migrating.mdx
index f66f0c6da3..6adeb8dba9 100644
--- a/website/docs/cli/cloud/migrating.mdx
+++ b/website/docs/cli/cloud/migrating.mdx
@@ -1,5 +1,7 @@
---
page_title: Initializing and Migrating to Terraform Cloud - Terraform CLI
+description: >-
+ Learn how to use the Terraform CLI to migrate local or remote state to Terraform Cloud.
---
# Initializing and Migrating
diff --git a/website/docs/cli/state/recover.mdx b/website/docs/cli/state/recover.mdx
index 0e95f95426..07675491c0 100644
--- a/website/docs/cli/state/recover.mdx
+++ b/website/docs/cli/state/recover.mdx
@@ -1,8 +1,8 @@
---
page_title: Recovering from State Disasters - Terraform CLI
-descriptin: >-
- Commands that allow you to restore state backups and override Terraform state
- protections.
+description: >-
+ Learn how to restore state backups and override Terraform state protections to fix state errors with the Terraform CLI.
+
---
# Recovering from State Disasters
diff --git a/website/docs/configuration/expressions.mdx b/website/docs/configuration/expressions.mdx
deleted file mode 100644
index 96966de774..0000000000
--- a/website/docs/configuration/expressions.mdx
+++ /dev/null
@@ -1,121 +0,0 @@
----
-page_title: Expressions Landing Page - Configuration Language
----
-
-# Expressions Landing Page
-
-To improve navigation, we've split the old Expressions page into several smaller
-pages.
-
-
-
-## Types and Values, Literal Expressions, Indices and Attributes
-
-Terraform's types are `string`, `number`, `bool`, `list`, `tuple`, `map`,
-`object`, and `null`.
-
-This information has moved to
-[Types and Values](/terraform/language/expressions/types).
-
-
-
-
-
-## References to Named Values (Resource Attributes, Variables, etc.)
-
-You can refer to certain values by name, like `var.some_variable` or
-`aws_instance.example.ami`.
-
-This information has moved to
-[References to Values](/terraform/language/expressions/references).
-
-
-
-
-
-## Arithmetic and Logical Operators
-
-Operators are expressions that transform other expressions, like adding two
-numbers (`+`) or comparing two values to get a bool (`==`, `>=`, etc.).
-
-This information has moved to
-[Operators](/terraform/language/expressions/operators).
-
-
-
-## Conditional Expressions
-
-The `condition ? true_val : false_val` expression chooses between two
-expressions based on a bool condition.
-
-This information has moved to
-[Conditional Expressions](/terraform/language/expressions/conditionals).
-
-
-
-
-
-## Function Calls
-
-Terraform's functions can be called like `function_name(arg1, arg2)`.
-
-This information has moved to
-[Function Calls](/terraform/language/expressions/function-calls).
-
-
-
-
-
-## `for` Expressions
-
-Expressions like `[for s in var.list : upper(s)]` can transform a complex type
-value into another complex type value.
-
-This information has moved to
-[For Expressions](/terraform/language/expressions/for).
-
-
-
-
-
-## Splat Expressions
-
-Expressions like `var.list[*].id` can extract simpler collections from complex
-collections.
-
-This information has moved to
-[Splat Expressions](/terraform/language/expressions/splat).
-
-
-
-
-
-## `dynamic` Blocks
-
-The special `dynamic` block type serves the same purpose as a `for` expression,
-except it creates multiple repeatable nested blocks instead of a complex value.
-
-This information has moved to
-[Dynamic Blocks](/terraform/language/expressions/dynamic-blocks).
-
-
-
-
-
-## String Literals and String Templates
-
-Strings can be `"double-quoted"` or
-
-```hcl
-<
diff --git a/website/docs/configuration/index.mdx b/website/docs/configuration/index.mdx
deleted file mode 100644
index 046abeac20..0000000000
--- a/website/docs/configuration/index.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
----
-page_title: Terraform Configuration
----
-
-# Terraform Configuration
diff --git a/website/docs/configuration/modules.mdx b/website/docs/configuration/modules.mdx
deleted file mode 100644
index de91ee4c60..0000000000
--- a/website/docs/configuration/modules.mdx
+++ /dev/null
@@ -1,39 +0,0 @@
----
-page_title: Modules Landing Page - Configuration Language
----
-
-# Modules Landing Page
-
-To improve navigation, we've split the old Modules page into several smaller
-pages.
-
-
-
-## Syntax and Elements of Module Blocks
-
-This information has moved to
-[Module Blocks](/terraform/language/modules/syntax).
-
-
-
-
-
-## Multiple Instances with `count` and `for_each`
-
-This information has moved to
-[`count`](/terraform/language/meta-arguments/count) and
-[`for_each`](/terraform/language/meta-arguments/for_each).
-
-
-
-
-
-## Handling Provider Configurations in Re-usable Modules
-
-This information has moved to
-[The `providers` Meta-Argument](/terraform/language/meta-arguments/module-providers)
-(for users of re-usable modules) and
-[Providers Within Modules](/terraform/language/modules/develop/providers)
-(for module developers).
-
-
diff --git a/website/docs/configuration/resources.mdx b/website/docs/configuration/resources.mdx
deleted file mode 100644
index 87f1495355..0000000000
--- a/website/docs/configuration/resources.mdx
+++ /dev/null
@@ -1,93 +0,0 @@
----
-page_title: Resources Landing Page - Configuration Language
----
-
-# Resources Landing Page
-
-To improve navigation, we've split the old Resources page into several smaller
-pages.
-
-
-
-## Syntax and Elements of Resource Blocks
-
-This information has moved to
-[Resource Blocks](/terraform/language/resources/syntax).
-
-
-
-
-
-## Details of Resource Behavior
-
-This information has moved to
-[Resource Behavior](/terraform/language/resources/behavior).
-
-
-
-## Resource Meta-Arguments
-
-Each resource meta-argument has moved to its own page:
-
-- [`depends_on`](/terraform/language/meta-arguments/depends_on)
-- [`count`](/terraform/language/meta-arguments/count)
-- [`for_each`](/terraform/language/meta-arguments/for_each)
-- [`provider`](/terraform/language/meta-arguments/resource-provider)
-- [`lifecycle`](/terraform/language/meta-arguments/lifecycle)
-- [Provisioners](/terraform/language/resources/provisioners/syntax)
-
-
-
-
-
-### `depends_on`
-
-This information has moved to
-[`depends_on`](/terraform/language/meta-arguments/depends_on).
-
-
-
-
-
-### `count`
-
-This information has moved to
-[`count`](/terraform/language/meta-arguments/count).
-
-
-
-
-
-### `for_each`
-
-This information has moved to
-[`for_each`](/terraform/language/meta-arguments/for_each).
-
-
-
-
-
-### `provider`
-
-This information has moved to
-[`provider`](/terraform/language/meta-arguments/resource-provider).
-
-
-
-
-
-### `lifecycle`
-
-This information has moved to
-[`lifecycle`](/terraform/language/meta-arguments/lifecycle).
-
-
-
-
-
-### Provisioners
-
-This information has moved to
-[Provisioners](/terraform/language/resources/provisioners/syntax).
-
-
diff --git a/website/docs/language/modules/develop/providers.mdx b/website/docs/language/modules/develop/providers.mdx
index 8a4a540082..16105057a5 100644
--- a/website/docs/language/modules/develop/providers.mdx
+++ b/website/docs/language/modules/develop/providers.mdx
@@ -1,5 +1,7 @@
---
page_title: Providers Within Modules - Configuration Language
+description: >-
+ Use providers within Terraform modules. Learn about version constraints, aliases, implicit inheritance, and passing providers to Terraform modules.
---
# Providers Within Modules
diff --git a/website/docs/language/modules/develop/structure.mdx b/website/docs/language/modules/develop/structure.mdx
index 1746648691..20ba5c9458 100644
--- a/website/docs/language/modules/develop/structure.mdx
+++ b/website/docs/language/modules/develop/structure.mdx
@@ -1,5 +1,7 @@
---
page_title: Standard Module Structure
+description: >-
+ Learn about the recommended file and directory structure for developing reusable modules distributed as separate repositories.
---
# Standard Module Structure
diff --git a/website/docs/language/modules/testing-experiment.mdx b/website/docs/language/modules/testing-experiment.mdx
deleted file mode 100644
index 95c766e717..0000000000
--- a/website/docs/language/modules/testing-experiment.mdx
+++ /dev/null
@@ -1,322 +0,0 @@
----
-page_title: Module Testing Experiment - Configuration Language
----
-
-# Module Testing Experiment
-
-This page is about some experimental features available in recent versions of
-Terraform CLI related to integration testing of shared modules.
-
-The Terraform team is aiming to use these features to gather feedback as part
-of ongoing research into different strategies for testing Terraform modules.
-These features are likely to change significantly in future releases based on
-feedback.
-
-## Current Research Goals
-
-Our initial area of research is into the question of whether it's helpful and
-productive to write module integration tests in the Terraform language itself,
-or whether it's better to handle that as a separate concern orchestrated by
-code written in other languages.
-
-Some existing efforts have piloted both approaches:
-
-* [Terratest](https://terratest.gruntwork.io/) and
- [kitchen-terraform](https://github.com/newcontext-oss/kitchen-terraform)
- both pioneered the idea of writing tests for Terraform modules with explicit
- orchestration written in the Go and Ruby programming languages, respectively.
-
-* The Terraform provider
- [`apparentlymart/testing`](https://registry.terraform.io/providers/apparentlymart/testing/latest)
- introduced the idea of writing Terraform module tests in the Terraform
- language itself, using a special provider that can evaluate assertions
- and fail `terraform apply` if they don't pass.
-
-Both of these approaches have both advantages and disadvantages, and so it's
-likely that both will coexist for different situations, but the community
-efforts have already explored the external-language testing model quite deeply
-while the Terraform-integrated testing model has not yet been widely trialled.
-For that reason, the current iteration of the module testing experiment is
-aimed at trying to make the Terraform-integrated approach more accessible so
-that more module authors can hopefully try it and share their experiences.
-
-## Current Experimental Features
-
--> This page describes the incarnation of the experimental features introduced
-in **Terraform CLI v0.15.0**. If you are using an earlier version of Terraform
-then you'll need to upgrade to v0.15.0 or later to use the experimental features
-described here, though you only need to use v0.15.0 or later for running tests;
-your module itself can remain compatible with earlier Terraform versions, if
-needed.
-
-Our current area of interest is in what sorts of tests can and cannot be
-written using features integrated into the Terraform language itself. As a
-means to investigate that without invasive, cross-cutting changes to Terraform
-Core we're using a special built-in Terraform provider as a placeholder for
-potential new features.
-
-If this experiment is successful then we expect to run a second round of
-research and design about exactly what syntax is most ergonomic for writing
-tests, but for the moment we're interested less in the specific syntax and more
-in the capabilities of this approach.
-
-The temporary extensions to Terraform for this experiment consist of the
-following parts:
-
-* A temporary experimental provider `terraform.io/builtin/test`, which acts as
- a placeholder for potential new language features related to test assertions.
-
-* A `terraform test` command for more conveniently running multiple tests in
- a single action.
-
-* An experimental convention of placing test configurations in subdirectories
- of a `tests` directory within your module, which `terraform test` will then
- discover and run.
-
-We would like to invite adventurous module authors to try writing integration
-tests for their modules using these mechanisms, and ideally also share the
-tests you write (in a temporary VCS branch, if necessary) so we can see what
-you were able to test, along with anything you felt unable to test in this way.
-
-If you're interested in giving this a try, see the following sections for
-usage details. Because these features are temporary experimental extensions,
-there's some boilerplate required to activate and make use of it which would
-likely not be required in a final design.
-
-### Writing Tests for a Module
-
-For the purposes of the current experiment, module tests are arranged into
-_test suites_, each of which is a root Terraform module which includes a
-`module` block calling the module under test, and ideally also a number of
-test assertions to verify that the module outputs match expectations.
-
-In the same directory where you keep your module's `.tf` and/or `.tf.json`
-source files, create a subdirectory called `tests`. Under that directory,
-make another directory which will serve as your first test suite, with a
-directory name that concisely describes what the suite is aiming to test.
-
-Here's an example directory structure of a typical module directory layout
-with the addition of a test suite called `defaults`:
-
-```
-main.tf
-outputs.tf
-providers.tf
-variables.tf
-versions.tf
-tests/
- defaults/
- test_defaults.tf
-```
-
-The `tests/defaults/test_defaults.tf` file will contain a call to the
-main module with a suitable set of arguments and hopefully also one or more
-resources that will, for the sake of the experiment, serve as the temporary
-syntax for defining test assertions. For example:
-
-```hcl
-terraform {
- required_providers {
- # Because we're currently using a built-in provider as
- # a substitute for dedicated Terraform language syntax
- # for now, test suite modules must always declare a
- # dependency on this provider. This provider is only
- # available when running tests, so you shouldn't use it
- # in non-test modules.
- test = {
- source = "terraform.io/builtin/test"
- }
-
- # This example also uses the "http" data source to
- # verify the behavior of the hypothetical running
- # service, so we should declare that too.
- http = {
- source = "hashicorp/http"
- }
- }
-}
-
-module "main" {
- # source is always ../.. for test suite configurations,
- # because they are placed two subdirectories deep under
- # the main module directory.
- source = "../.."
-
- # This test suite is aiming to test the "defaults" for
- # this module, so it doesn't set any input variables
- # and just lets their default values be selected instead.
-}
-
-# As with all Terraform modules, we can use local values
-# to do any necessary post-processing of the results from
-# the module in preparation for writing test assertions.
-locals {
- # This expression also serves as an implicit assertion
- # that the base URL uses URL syntax; the test suite
- # will fail if this function fails.
- api_url_parts = regex(
- "^(?:(?P[^:/?#]+):)?(?://(?P[^/?#]*))?",
- module.main.api_url,
- )
-}
-
-# The special test_assertions resource type, which belongs
-# to the test provider we required above, is a temporary
-# syntax for writing out explicit test assertions.
-resource "test_assertions" "api_url" {
- # "component" serves as a unique identifier for this
- # particular set of assertions in the test results.
- component = "api_url"
-
- # equal and check blocks serve as the test assertions.
- # the labels on these blocks are unique identifiers for
- # the assertions, to allow more easily tracking changes
- # in success between runs.
-
- equal "scheme" {
- description = "default scheme is https"
- got = local.api_url_parts.scheme
- want = "https"
- }
-
- check "port_number" {
- description = "default port number is 8080"
- condition = can(regex(":8080$", local.api_url_parts.authority))
- }
-}
-
-# We can also use data resources to respond to the
-# behavior of the real remote system, rather than
-# just to values within the Terraform configuration.
-data "http" "api_response" {
- depends_on = [
- # make sure the syntax assertions run first, so
- # we'll be sure to see if it was URL syntax errors
- # that let to this data resource also failing.
- test_assertions.api_url,
- ]
-
- url = module.main.api_url
-}
-
-resource "test_assertions" "api_response" {
- component = "api_response"
-
- check "valid_json" {
- description = "base URL responds with valid JSON"
- condition = can(jsondecode(data.http.api_response.body))
- }
-}
-```
-
-If you like, you can create additional directories alongside
-the `default` directory to define additional test suites that
-pass different variable values into the main module, and
-then include assertions that verify that the result has changed
-in the expected way.
-
-### Running Your Tests
-
-The `terraform test` command aims to make it easier to exercise all of your
-defined test suites at once, and see only the output related to any test
-failures or errors.
-
-The current experimental incarnation of this command expects to be run from
-your main module directory. In our example directory structure above,
-that was the directory containing `main.tf` etc, and _not_ the specific test
-suite directory containing `test_defaults.tf`.
-
-Because these test suites are integration tests rather than unit tests, you'll
-need to set up any credentials files or environment variables needed by the
-providers your module uses before running `terraform test`. The test command
-will, for each suite:
-
-* Install the providers and any external modules the test configuration depends
- on.
-* Create an execution plan to create the objects declared in the module.
-* Apply that execution plan to create the objects in the real remote system.
-* Collect all of the test results from the apply step, which would also have
- "created" the `test_assertions` resources.
-* Destroy all of the objects recorded in the temporary test state, as if running
- `terraform destroy` against the test configuration.
-
-```shellsession
-$ terraform test
-─── Failed: defaults.api_url.scheme (default scheme is https) ───────────────
-wrong value
- got: "http"
- want: "https"
-─────────────────────────────────────────────────────────────────────────────
-```
-
-In this case, it seems like the module returned an `http` rather than an
-`https` URL in the default case, and so the `defaults.api_url.scheme`
-assertion failed, and the `terraform test` command detected and reported it.
-
-The `test_assertions` resource captures any assertion failures but does not
-return an error, because that can then potentially allow downstream
-assertions to also run and thus capture as much context as possible.
-However, if Terraform encounters any _errors_ while processing the test
-configuration it will halt processing, which may cause some of the test
-assertions to be skipped.
-
-## Known Limitations
-
-The design above is very much a prototype aimed at gathering more experience
-with the possibilities of testing inside the Terraform language. We know it's
-currently somewhat non-ergonomic, and hope to improve on that in later phases
-of research and design, but the main focus of this iteration is on available
-functionality and so with that in mind there are some specific possibilities
-that we know the current prototype doesn't support well:
-
-* Testing of subsequent updates to an existing deployment of a module.
- Tests written in this way can only exercise the create and destroy
- behaviors.
-
-* Assertions about expected errors. For a module that includes variable
- validation rules and data resources that function as assertion checks,
- the current prototype doesn't have any way to express that a particular
- set of inputs is _expected_ to produce an error, and thus report a test
- failure if it doesn't. We'll hopefully be able to improve on this in a future
- iteration with the test assertions better integrated into the language.
-
-* Capturing context about failures. Due to this prototype using a provider as
- an approximation for new assertion syntax, the `terraform test` command is
- limited in how much context it's able to gather about failures. A design
- more integrated into the language could potentially capture the source
- expressions and input values to give better feedback about what went wrong,
- similar to what Terraform typically returns from expression evaluation errors
- in the main language.
-
-* Unit testing without creating real objects. Although we do hope to spend more
- time researching possibilities for unit testing against fake test doubles in
- the future, we've decided to focus on integration testing to start because
- it feels like the better-defined problem.
-
-## Sending Feedback
-
-The sort of feedback we'd most like to see at this stage of the experiment is
-to see the source code of any tests you've written against real modules using
-the features described above, along with notes about anything that you
-attempted to test but were blocked from doing so by limitations of the above
-features. The most ideal way to share that would be to share a link to a
-version control branch where you've added such tests, if your module is open
-source.
-
-If you've previously written or attempted to write tests in an external
-language, using a system like Terratest or kitchen-terraform, we'd also be
-interested to hear about comparative differences between the two: what worked
-well in each and what didn't work so well.
-
-Our ultimate goal is to work towards an integration testing methodology which
-strikes the best compromise between the capabilities of these different
-approaches, ideally avoiding a hard requirement on any particular external
-language and fitting well into the Terraform workflow.
-
-Since this is still early work and likely to lead to unstructured discussion,
-we'd like to gather feedback primarily via new topics in
-[the community forum](https://discuss.hashicorp.com/c/terraform-core/27). That
-way we can have some more freedom to explore different ideas and approaches
-without the structural requirements we typically impose on GitHub issues.
-
-Any feedback you'd like to share would be very welcome!
diff --git a/website/docs/language/settings/backends/configuration.mdx b/website/docs/language/settings/backends/configuration.mdx
index ffcee8fef6..321392674b 100644
--- a/website/docs/language/settings/backends/configuration.mdx
+++ b/website/docs/language/settings/backends/configuration.mdx
@@ -1,5 +1,7 @@
---
page_title: Backend Configuration - Configuration Language
+description: >-
+ Use the `backend` block to control where Terraform stores state. Learn about the available state backends, the backend block, initializing backends, partial backend configuration, changing backend configuration, and unconfiguring a backend.
---
# Backend Configuration