From 34727c5680972d913f8a26973673c749b354f531 Mon Sep 17 00:00:00 2001 From: Kazuya INOUE Date: Mon, 21 Oct 2024 22:32:13 +0900 Subject: [PATCH 01/13] Fix typo: correct "infrastruture" to "infrastructure" --- website/docs/language/backend/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/language/backend/index.mdx b/website/docs/language/backend/index.mdx index 9399b98303..b77d670674 100644 --- a/website/docs/language/backend/index.mdx +++ b/website/docs/language/backend/index.mdx @@ -84,7 +84,7 @@ or state operations. After you initialize, Terraform creates a `.terraform/` directory locally. This directory contains the most recent backend configuration, including any authentication parameters you provided to the Terraform CLI. Do not check this directory into Git, as it may contain sensitive credentials for your remote backend. -The local backend configuration is different and entirely separate from the `terraform.tfstate` file that contains [state data](/terraform/language/state) about your real-world infrastruture. Terraform stores the `terraform.tfstate` file in your remote backend. +The local backend configuration is different and entirely separate from the `terraform.tfstate` file that contains [state data](/terraform/language/state) about your real-world infrastructure. Terraform stores the `terraform.tfstate` file in your remote backend. When you change backends, Terraform gives you the option to migrate your state to the new backend. This lets you adopt backends without losing From cad5b574052e97ff569d2ec5c1c53b40c2825ae6 Mon Sep 17 00:00:00 2001 From: Raimar Falke Date: Thu, 24 Oct 2024 20:52:15 +0200 Subject: [PATCH 02/13] Clarify single-removal behavior in `trimsuffix` and `trimprefix` docs --- website/docs/language/functions/trimprefix.mdx | 7 ++++++- website/docs/language/functions/trimsuffix.mdx | 12 +++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/website/docs/language/functions/trimprefix.mdx b/website/docs/language/functions/trimprefix.mdx index 51b931bdb1..195cacd455 100644 --- a/website/docs/language/functions/trimprefix.mdx +++ b/website/docs/language/functions/trimprefix.mdx @@ -7,7 +7,7 @@ description: |- # `trimprefix` Function -`trimprefix` removes the specified prefix from the start of the given string. If the string does not start with the prefix, the string is returned unchanged. +`trimprefix` removes the specified prefix from the start of the given string, but only once. If the string does not begin with the prefix, the original string is returned unchanged. ## Examples @@ -21,6 +21,11 @@ world helloworld ``` +``` +> trimprefix("--hello", "-") +-hello +``` + ## Related Functions * [`trim`](/terraform/language/functions/trim) removes characters at the start and end of a string. diff --git a/website/docs/language/functions/trimsuffix.mdx b/website/docs/language/functions/trimsuffix.mdx index 31f12f225a..272d0cc48e 100644 --- a/website/docs/language/functions/trimsuffix.mdx +++ b/website/docs/language/functions/trimsuffix.mdx @@ -7,7 +7,7 @@ description: |- # `trimsuffix` Function -`trimsuffix` removes the specified suffix from the end of the given string. +`trimsuffix` removes the specified suffix from the end of the given string, but only once, even if the suffix appears multiple times. If the suffix does not appear at the very end of the string, the original string is returned unchanged. ## Examples @@ -16,6 +16,16 @@ description: |- hello ``` +``` +> trimsuffix("helloworld", "cat") +helloworld +``` + +``` +> trimsuffix("hello--", "-") +hello- +``` + ## Related Functions * [`trim`](/terraform/language/functions/trim) removes characters at the start and end of a string. From 8bdc1c8e3f6a767fcd750274563919e5a0657210 Mon Sep 17 00:00:00 2001 From: trujillo-adam Date: Mon, 18 Nov 2024 16:06:08 -0800 Subject: [PATCH 03/13] fixes #32423 --- .../expressions/version-constraints.mdx | 103 +++++++++--------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/website/docs/language/expressions/version-constraints.mdx b/website/docs/language/expressions/version-constraints.mdx index 880d31a00e..a54c6f088b 100644 --- a/website/docs/language/expressions/version-constraints.mdx +++ b/website/docs/language/expressions/version-constraints.mdx @@ -5,88 +5,89 @@ description: >- providers, and Terraform itself. Learn version constraint syntax and behavior. --- -# Version Constraints +# Version constraints -Anywhere that Terraform lets you specify a range of acceptable versions for -something, it expects a specially formatted string known as a version -constraint. Version constraints are used when configuring: +This topic provides reference information about the version constraints syntax in Terraform configuration language. + +## Introduction + +Terraform lets you specify a range of acceptable versions for +components you define in the configuration. Terraform expects a specially-formatted string to constrain the versions of the component. You can specify version constraints when configuring the following components: - [Modules](/terraform/language/modules) - [Provider requirements](/terraform/language/providers/requirements) - [The `required_version` setting](/terraform/language/terraform#terraform-required_version) in the `terraform` block. -## Version Constraint Syntax - -Terraform's syntax for version constraints is very similar to the syntax used by -other dependency management systems like Bundler and npm. - -```hcl -version = ">= 1.2.0, < 2.0.0" -``` +## Version constraint syntax A version constraint is a [string literal](/terraform/language/expressions/strings) -containing one or more conditions, which are separated by commas. +containing one or more conditions separated by commas. Each condition consists of an operator and a version number. -Version numbers should be a series of numbers separated by periods (like -`1.2.0`), optionally with a suffix to indicate a beta release. +Version numbers are a series of numbers separated by periods, for example `1.2.0`. It is optional, but you can include a suffix to indicate a beta release. Refer to [Specify a pre-release version](#specify-a-pre-release-version) for additional information. -The following operators are valid: +Use the following syntax to specify version constraints: -- `=` (or no operator): Allows only one exact version number. Cannot be combined - with other conditions. +```hcl +version = " " +``` -- `!=`: Excludes an exact version number. +In the following example, Terraform installs a versions `1.2.0` and newer, as well as version older than `2.0.0`: -- `>`, `>=`, `<`, `<=`: Comparisons against a specified version, allowing - versions for which the comparison is true. "Greater-than" requests newer - versions, and "less-than" requests older versions. +```hcl +version = ">= 1.2.0, < 2.0.0" +``` + +## Operators -- `~>`: Allows only the _rightmost_ version component to increment. This format is referred to as the _pessimistic constraint_ operator. For example, - to allow new patch releases within a specific minor release, use the full - version number: - - `~> 1.0.4`: Allows Terraform to install `1.0.5` and `1.0.10` but not `1.1.0`. - - `~> 1.1`: Allows Terraform to install `1.2` and `1.10` but not `2.0`. +The following table describes the operators you can use to configure version constraints: -## Version Constraint Behavior +| Operator | Description | +| --- | --- | +| `=`,
no operator | Allows only one exact version number. Cannot be combined with other conditions. | +| `!=` | Excludes an exact version number. | +| `>`,
`>=`,
`<`,
`<=` | Compares to a specified version. Terraform allows versions that resolve to `true`. The `>` and `>=` operators request newer versions. The `<` and `<=` operators request older versions. | +| `~>` | Allows only the right-most version component to increment. Examples:
  • `~> 1.0.4`: Allows Terraform to install `1.0.5` and `1.0.10` but not `1.1.0`.
  • `1.1`: Allows Terraform to install `1.2` and `1.10` but not `2.0`.
| -A version number that meets every applicable constraint is considered acceptable. +## Version constraint behavior + +Terraform uses versions that meet all applicable constraints. Terraform consults version constraints to determine whether it has acceptable versions of itself, any required provider plugins, and any required modules. For -plugins and modules, it will use the newest installed version that meets the +plugins and modules, Terraform uses the newest installed version that meets the applicable constraints. -If Terraform doesn't have an acceptable version of a required plugin or module, -it will attempt to download the newest version that meets the applicable +When Terraform does not have an acceptable version of a required plugin or module, +it attempts to download the newest version that meets the applicable constraints. -If Terraform isn't able to obtain acceptable versions of external dependencies, -or if it doesn't have an acceptable version of itself, it won't proceed with any -plans, applies, or state manipulation actions. +When Terraform is unable to obtain acceptable versions of external dependencies +or if it does not have an acceptable version of itself, then it does not proceed with any +`terraform plan`, `terraform apply`, or `terraform state` operations. + +The root module and any child modules can constrain the Terraform version and any provider versions the modules use. Terraform considers these constraints +equal, and only proceeds if all are met. + +### Specify a pre-release version + +A pre-release version is a version number that contains a suffix introduced by +a dash, for example `1.2.0-beta`. To configure Terraform to select a pre-release version, set the exact version number using the `=` operator. You can also omit the operator and specify the exact pre-release version. Terraform does not match pre-release versions on `>`, `>=`, `<`, `<=`, or `~>` operators. -Both the root module and any child module can constrain the acceptable versions -of Terraform and any providers they use. Terraform considers these constraints -equal, and will only proceed if all of them can be met. +## Best practices -A prerelease version is a version number that contains a suffix introduced by -a dash, like `1.2.0-beta`. A prerelease version can be selected only by an -_exact_ version constraint (the `=` operator or no operator). Prerelease -versions do not match inexact operators such as `>=`, `~>`, etc. +We recommend implementing the following best practices when configuration version constraints. -## Best Practices +### Module versions -### Module Versions +- Require specific versions to ensure that updates only happen when convenient to you when your infrastructure depencds on third-party modules. -- When depending on third-party modules, require specific versions to ensure - that updates only happen when convenient to you. +- Specify version ranges when your organization consistently uses semantic versioning for modules it maintains. -- For modules maintained within your organization, specifying version ranges - may be appropriate if semantic versioning is used consistently or if there is - a well-defined release process that avoids unwanted updates. +- Specify version ranges when your organization follows a well-defined release process that avoids unwanted updates. -### Terraform Core and Provider Versions +### Terraform core and provider versions - Reusable modules should constrain only their minimum allowed versions of Terraform and providers, such as `>= 0.12.0`. This helps avoid known @@ -94,4 +95,4 @@ versions do not match inexact operators such as `>=`, `~>`, etc. upgrade to newer versions of Terraform without altering the module. - Root modules should use a `~>` constraint to set both a lower and upper bound - on versions for each provider they depend on. + on versions for each provider they depend on. \ No newline at end of file From 9402a85c5d9059be6c0539df9264870aaedde4fc Mon Sep 17 00:00:00 2001 From: Liam Cervante Date: Tue, 19 Nov 2024 08:56:51 +0100 Subject: [PATCH 04/13] Update noisy equivalence test (#36036) * update noisy equivalence test * also run on opened PRs * don't need to ignore fields anymore --- .github/actions/equivalence-test/action.yml | 1 + .github/workflows/equivalence-test-diff.yml | 1 + .github/workflows/equivalence-test-update.yml | 2 +- .../tests/null_provider_basic/spec.json | 13 --------- .../null_provider_update/.terraform.lock.hcl | 22 +++++++++++++++ .../main.tf | 0 .../tests/null_provider_update/spec.json | 5 ++++ .../null_provider_update/terraform.tfstate | 27 +++++++++++++++++++ 8 files changed, 57 insertions(+), 14 deletions(-) delete mode 100644 testing/equivalence-tests/tests/null_provider_basic/spec.json create mode 100644 testing/equivalence-tests/tests/null_provider_update/.terraform.lock.hcl rename testing/equivalence-tests/tests/{null_provider_basic => null_provider_update}/main.tf (100%) create mode 100644 testing/equivalence-tests/tests/null_provider_update/spec.json create mode 100644 testing/equivalence-tests/tests/null_provider_update/terraform.tfstate diff --git a/.github/actions/equivalence-test/action.yml b/.github/actions/equivalence-test/action.yml index bcde18329e..127af9ce80 100644 --- a/.github/actions/equivalence-test/action.yml +++ b/.github/actions/equivalence-test/action.yml @@ -70,6 +70,7 @@ runs: shell: bash run: | gh pr create \ + --draft \ --base ${{ inputs.current-branch }} \ --head ${{ inputs.new-branch }} \ --title "Update equivalence test golden files" \ diff --git a/.github/workflows/equivalence-test-diff.yml b/.github/workflows/equivalence-test-diff.yml index fed8b5bf3f..f5cdf3f6d5 100644 --- a/.github/workflows/equivalence-test-diff.yml +++ b/.github/workflows/equivalence-test-diff.yml @@ -3,6 +3,7 @@ name: equivalence-test-diff on: pull_request: types: + - opened - synchronize - ready_for_review - reopened diff --git a/.github/workflows/equivalence-test-update.yml b/.github/workflows/equivalence-test-update.yml index 9cd1e5d6bb..b194cd3437 100644 --- a/.github/workflows/equivalence-test-update.yml +++ b/.github/workflows/equivalence-test-update.yml @@ -66,4 +66,4 @@ jobs: current-branch: ${{ github.event.pull_request.base.ref }} new-branch: equivalence-testing/${{ github.event.pull_request.head.ref }} reviewers: ${{ github.event.pull_request.merged_by.login }} - message: "Update equivalence test golden files after ${{ github.event.pull_request.url }}." + message: "Update equivalence test golden files after ${{ github.event.pull_request.html_url }}." diff --git a/testing/equivalence-tests/tests/null_provider_basic/spec.json b/testing/equivalence-tests/tests/null_provider_basic/spec.json deleted file mode 100644 index d32d9a3b25..0000000000 --- a/testing/equivalence-tests/tests/null_provider_basic/spec.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "description": "tests creating a simple resource created by the null provider", - "include_files": [], - "ignore_fields": { - "apply.json": [ - "2.@message", - "2.hook.id_value" - ], - "state.json": [ - "values.root_module.resources.*.values.id" - ] - } -} diff --git a/testing/equivalence-tests/tests/null_provider_update/.terraform.lock.hcl b/testing/equivalence-tests/tests/null_provider_update/.terraform.lock.hcl new file mode 100644 index 0000000000..6ed19d1db2 --- /dev/null +++ b/testing/equivalence-tests/tests/null_provider_update/.terraform.lock.hcl @@ -0,0 +1,22 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/null" { + version = "3.1.1" + constraints = "3.1.1" + hashes = [ + "h1:YvH6gTaQzGdNv+SKTZujU1O0bO+Pw6vJHOPhqgN8XNs=", + "zh:063466f41f1d9fd0dd93722840c1314f046d8760b1812fa67c34de0afcba5597", + "zh:08c058e367de6debdad35fc24d97131c7cf75103baec8279aba3506a08b53faf", + "zh:73ce6dff935150d6ddc6ac4a10071e02647d10175c173cfe5dca81f3d13d8afe", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:8fdd792a626413502e68c195f2097352bdc6a0df694f7df350ed784741eb587e", + "zh:976bbaf268cb497400fd5b3c774d218f3933271864345f18deebe4dcbfcd6afa", + "zh:b21b78ca581f98f4cdb7a366b03ae9db23a73dfa7df12c533d7c19b68e9e72e5", + "zh:b7fc0c1615dbdb1d6fd4abb9c7dc7da286631f7ca2299fb9cd4664258ccfbff4", + "zh:d1efc942b2c44345e0c29bc976594cb7278c38cfb8897b344669eafbc3cddf46", + "zh:e356c245b3cd9d4789bab010893566acace682d7db877e52d40fc4ca34a50924", + "zh:ea98802ba92fcfa8cf12cbce2e9e7ebe999afbf8ed47fa45fc847a098d89468b", + "zh:eff8872458806499889f6927b5d954560f3d74bf20b6043409edf94d26cd906f", + ] +} diff --git a/testing/equivalence-tests/tests/null_provider_basic/main.tf b/testing/equivalence-tests/tests/null_provider_update/main.tf similarity index 100% rename from testing/equivalence-tests/tests/null_provider_basic/main.tf rename to testing/equivalence-tests/tests/null_provider_update/main.tf diff --git a/testing/equivalence-tests/tests/null_provider_update/spec.json b/testing/equivalence-tests/tests/null_provider_update/spec.json new file mode 100644 index 0000000000..fcd4cd67bc --- /dev/null +++ b/testing/equivalence-tests/tests/null_provider_update/spec.json @@ -0,0 +1,5 @@ +{ + "description": "tests creating a simple resource created by the null provider", + "include_files": [], + "ignore_fields": {} +} diff --git a/testing/equivalence-tests/tests/null_provider_update/terraform.tfstate b/testing/equivalence-tests/tests/null_provider_update/terraform.tfstate new file mode 100644 index 0000000000..c3b48aedfa --- /dev/null +++ b/testing/equivalence-tests/tests/null_provider_update/terraform.tfstate @@ -0,0 +1,27 @@ +{ + "version": 4, + "terraform_version": "1.10.0", + "serial": 1, + "lineage": "afca9e36-5040-2a11-9225-a64c8caa4605", + "outputs": {}, + "resources": [ + { + "mode": "managed", + "type": "null_resource", + "name": "null_resource", + "provider": "provider[\"registry.terraform.io/hashicorp/null\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "3637779521417605172", + "triggers": null + }, + "sensitive_attributes": [], + "private": "bnVsbA==" + } + ] + } + ], + "check_results": null +} From 4a69eec07cd4cc51c47fbb9de4e2193443011ede Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Tue, 19 Nov 2024 04:20:21 -0500 Subject: [PATCH 05/13] backend/s3: upgrade guide notes for Terraform 1.10 (#36037) This includes sections on the introduction of S3 native state locking and the removal of deprecated root level attributes related to role assumption which have been replaced by the `assume_role` block. --- .../docs/language/upgrade-guides/index.mdx | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/website/docs/language/upgrade-guides/index.mdx b/website/docs/language/upgrade-guides/index.mdx index 3cb0b10478..fc490ffd67 100644 --- a/website/docs/language/upgrade-guides/index.mdx +++ b/website/docs/language/upgrade-guides/index.mdx @@ -26,3 +26,44 @@ to discuss it. Moved blocks now respect reserved keywords such as `local`, `each`, `self` etc. when parsing resource addresses. Configurations that reference resources with type names that match top level blocks and keywords from moved blocks will need to prepend the reference identifier with `resource.`. + +## S3 Backend + +### S3 Native State Locking + +The S3 backend now supports S3 native state locking as an opt-in, experimental feature. +An S3 lock can be used alongside a DynamoDB lock, or independently. +When both locking mechanisms are configured, a lock must be successfully acquired from both locations before subsequent operations will proceed. + +To opt-in to S3 native state locking, set `use_lockfile` to `true`. + +```terraform +terraform { + backend "s3" { + # additional configuration omitted for brevity + use_lockfile = true + } +} +``` + +With S3 locking enabled, a lock file will be placed in the same location as the state file. +The lock file will be named identically to the state file, but with a `.tflock` extension. +**S3 bucket policies and IAM policies attached to the calling principal may need to be adjusted to include permissions for the new lock file.** + +In a future minor version of Terraform the experimental label will be removed from the `use_lockfile` attribute and attributes related to DynamoDB based locking will be deprecated. + +### Root Assume Role Attribute Removal + +Several root level attributes related to IAM role assumption which were previously deprecated have been removed. +Each removed field has an analogous field inside the [`assume_role` block](https://developer.hashicorp.com/terraform/language/backend/s3#assume-role-configuration) which should be used instead. + +| Removed | Replacement | +| --- | --- | +| `role_arn` | `assume_role.role_arn` | +| `session_name` | `assume_role.session_name` | +| `external_id` | `assume_role.external_id` | +| `assume_role_duration_seconds` | `assume_role.duration` | +| `assume_role_policy` | `assume_role.policy` | +| `assume_role_policy_arns` | `assume_role.policy_arn` | +| `assume_role_tags` | `assume_role.tags` | +| `assume_role_transitive_tag_keys` | `assume_role.transitive_tag_keys` | From 3e2878f148591cc49c69b0626e781a77defb66bd Mon Sep 17 00:00:00 2001 From: Liam Cervante Date: Tue, 19 Nov 2024 15:04:23 +0100 Subject: [PATCH 06/13] equivalence testing: update git operations (#36056) * equivalence testing: use --intent-to-add to include new file diffs * also update github commit name --- .github/actions/equivalence-test/action.yml | 5 +- .../outputs/null_provider_basic/apply.json | 77 ------------------- .../outputs/null_provider_basic/plan | 20 ----- .../outputs/null_provider_basic/plan.json | 68 ---------------- .../outputs/null_provider_basic/state | 4 - .../outputs/null_provider_basic/state.json | 21 ----- 6 files changed, 3 insertions(+), 192 deletions(-) delete mode 100644 testing/equivalence-tests/outputs/null_provider_basic/apply.json delete mode 100644 testing/equivalence-tests/outputs/null_provider_basic/plan delete mode 100644 testing/equivalence-tests/outputs/null_provider_basic/plan.json delete mode 100644 testing/equivalence-tests/outputs/null_provider_basic/state delete mode 100644 testing/equivalence-tests/outputs/null_provider_basic/state.json diff --git a/.github/actions/equivalence-test/action.yml b/.github/actions/equivalence-test/action.yml index 127af9ce80..cbfc51505e 100644 --- a/.github/actions/equivalence-test/action.yml +++ b/.github/actions/equivalence-test/action.yml @@ -51,6 +51,7 @@ runs: --goldens=testing/equivalence-tests/outputs \ --binary=$(pwd)/bin/terraform + git add --intent-to-add testing/equivalence-tests/outputs changed=$(git diff --quiet -- testing/equivalence-tests/outputs || echo true) echo "changed=$changed" >> "${GITHUB_OUTPUT}" @@ -58,8 +59,8 @@ runs: if: steps.execute.outputs.changed == 'true' shell: bash run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config user.name "hc-github-team-tf-core" + git config user.email "github-team-tf-core@hashicorp.com" git checkout -b ${{ inputs.new-branch }} git add testing/equivalence-tests/outputs git commit -m "Update equivalence test golden files." diff --git a/testing/equivalence-tests/outputs/null_provider_basic/apply.json b/testing/equivalence-tests/outputs/null_provider_basic/apply.json deleted file mode 100644 index fc6c349468..0000000000 --- a/testing/equivalence-tests/outputs/null_provider_basic/apply.json +++ /dev/null @@ -1,77 +0,0 @@ -[ - { - "@level": "info", - "@message": "null_resource.null_resource: Plan to create", - "@module": "terraform.ui", - "change": { - "action": "create", - "resource": { - "addr": "null_resource.null_resource", - "implied_provider": "null", - "module": "", - "resource": "null_resource.null_resource", - "resource_key": null, - "resource_name": "null_resource", - "resource_type": "null_resource" - } - }, - "type": "planned_change" - }, - { - "@level": "info", - "@message": "null_resource.null_resource: Creating...", - "@module": "terraform.ui", - "hook": { - "action": "create", - "resource": { - "addr": "null_resource.null_resource", - "implied_provider": "null", - "module": "", - "resource": "null_resource.null_resource", - "resource_key": null, - "resource_name": "null_resource", - "resource_type": "null_resource" - } - }, - "type": "apply_start" - }, - { - "@level": "info", - "@module": "terraform.ui", - "hook": { - "action": "create", - "elapsed_seconds": 0, - "id_key": "id", - "resource": { - "addr": "null_resource.null_resource", - "implied_provider": "null", - "module": "", - "resource": "null_resource.null_resource", - "resource_key": null, - "resource_name": "null_resource", - "resource_type": "null_resource" - } - }, - "type": "apply_complete" - }, - { - "@level": "info", - "@message": "Apply complete! Resources: 1 added, 0 changed, 0 destroyed.", - "@module": "terraform.ui", - "changes": { - "add": 1, - "change": 0, - "import": 0, - "operation": "apply", - "remove": 0 - }, - "type": "change_summary" - }, - { - "@level": "info", - "@message": "Outputs: 0", - "@module": "terraform.ui", - "outputs": {}, - "type": "outputs" - } -] \ No newline at end of file diff --git a/testing/equivalence-tests/outputs/null_provider_basic/plan b/testing/equivalence-tests/outputs/null_provider_basic/plan deleted file mode 100644 index 79e0f32343..0000000000 --- a/testing/equivalence-tests/outputs/null_provider_basic/plan +++ /dev/null @@ -1,20 +0,0 @@ - -Terraform used the selected providers to generate the following execution -plan. Resource actions are indicated with the following symbols: - + create - -Terraform will perform the following actions: - - # null_resource.null_resource will be created - + resource "null_resource" "null_resource" { - + id = (known after apply) - } - -Plan: 1 to add, 0 to change, 0 to destroy. - -───────────────────────────────────────────────────────────────────────────── - -Saved the plan to: equivalence_test_plan - -To perform exactly these actions, run the following command to apply: - terraform apply "equivalence_test_plan" diff --git a/testing/equivalence-tests/outputs/null_provider_basic/plan.json b/testing/equivalence-tests/outputs/null_provider_basic/plan.json deleted file mode 100644 index f34bfa46e5..0000000000 --- a/testing/equivalence-tests/outputs/null_provider_basic/plan.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "applyable": true, - "complete": true, - "configuration": { - "provider_config": { - "null": { - "full_name": "registry.terraform.io/hashicorp/null", - "name": "null", - "version_constraint": "3.1.1" - } - }, - "root_module": { - "resources": [ - { - "address": "null_resource.null_resource", - "mode": "managed", - "name": "null_resource", - "provider_config_key": "null", - "schema_version": 0, - "type": "null_resource" - } - ] - } - }, - "errored": false, - "format_version": "1.2", - "planned_values": { - "root_module": { - "resources": [ - { - "address": "null_resource.null_resource", - "mode": "managed", - "name": "null_resource", - "provider_name": "registry.terraform.io/hashicorp/null", - "schema_version": 0, - "sensitive_values": {}, - "type": "null_resource", - "values": { - "triggers": null - } - } - ] - } - }, - "resource_changes": [ - { - "address": "null_resource.null_resource", - "change": { - "actions": [ - "create" - ], - "after": { - "triggers": null - }, - "after_sensitive": {}, - "after_unknown": { - "id": true - }, - "before": null, - "before_sensitive": false - }, - "mode": "managed", - "name": "null_resource", - "provider_name": "registry.terraform.io/hashicorp/null", - "type": "null_resource" - } - ] -} \ No newline at end of file diff --git a/testing/equivalence-tests/outputs/null_provider_basic/state b/testing/equivalence-tests/outputs/null_provider_basic/state deleted file mode 100644 index e719844c60..0000000000 --- a/testing/equivalence-tests/outputs/null_provider_basic/state +++ /dev/null @@ -1,4 +0,0 @@ -# null_resource.null_resource: -resource "null_resource" "null_resource" { - id = "5363570677767575363" -} diff --git a/testing/equivalence-tests/outputs/null_provider_basic/state.json b/testing/equivalence-tests/outputs/null_provider_basic/state.json deleted file mode 100644 index cf3dc5865e..0000000000 --- a/testing/equivalence-tests/outputs/null_provider_basic/state.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "format_version": "1.0", - "values": { - "root_module": { - "resources": [ - { - "address": "null_resource.null_resource", - "mode": "managed", - "name": "null_resource", - "provider_name": "registry.terraform.io/hashicorp/null", - "schema_version": 0, - "sensitive_values": {}, - "type": "null_resource", - "values": { - "triggers": null - } - } - ] - } - } -} \ No newline at end of file From 3065fdb14dca72f36ddc809dc6e18ea80094011a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 15:24:43 +0100 Subject: [PATCH 07/13] Update equivalence test golden files. (#36060) Co-authored-by: hc-github-team-tf-core --- .../outputs/null_provider_update/apply.json | 22 +++++ .../outputs/null_provider_update/plan | 6 ++ .../outputs/null_provider_update/plan.json | 93 +++++++++++++++++++ .../outputs/null_provider_update/state | 4 + .../outputs/null_provider_update/state.json | 22 +++++ 5 files changed, 147 insertions(+) create mode 100644 testing/equivalence-tests/outputs/null_provider_update/apply.json create mode 100644 testing/equivalence-tests/outputs/null_provider_update/plan create mode 100644 testing/equivalence-tests/outputs/null_provider_update/plan.json create mode 100644 testing/equivalence-tests/outputs/null_provider_update/state create mode 100644 testing/equivalence-tests/outputs/null_provider_update/state.json diff --git a/testing/equivalence-tests/outputs/null_provider_update/apply.json b/testing/equivalence-tests/outputs/null_provider_update/apply.json new file mode 100644 index 0000000000..42438bd2f7 --- /dev/null +++ b/testing/equivalence-tests/outputs/null_provider_update/apply.json @@ -0,0 +1,22 @@ +[ + { + "@level": "info", + "@message": "Apply complete! Resources: 0 added, 0 changed, 0 destroyed.", + "@module": "terraform.ui", + "changes": { + "add": 0, + "change": 0, + "import": 0, + "operation": "apply", + "remove": 0 + }, + "type": "change_summary" + }, + { + "@level": "info", + "@message": "Outputs: 0", + "@module": "terraform.ui", + "outputs": {}, + "type": "outputs" + } +] \ No newline at end of file diff --git a/testing/equivalence-tests/outputs/null_provider_update/plan b/testing/equivalence-tests/outputs/null_provider_update/plan new file mode 100644 index 0000000000..c2ee48084b --- /dev/null +++ b/testing/equivalence-tests/outputs/null_provider_update/plan @@ -0,0 +1,6 @@ +null_resource.null_resource: Refreshing state... [id=3637779521417605172] + +No changes. Your infrastructure matches the configuration. + +Terraform has compared your real infrastructure against your configuration +and found no differences, so no changes are needed. diff --git a/testing/equivalence-tests/outputs/null_provider_update/plan.json b/testing/equivalence-tests/outputs/null_provider_update/plan.json new file mode 100644 index 0000000000..ef949f810c --- /dev/null +++ b/testing/equivalence-tests/outputs/null_provider_update/plan.json @@ -0,0 +1,93 @@ +{ + "applyable": false, + "complete": true, + "configuration": { + "provider_config": { + "null": { + "full_name": "registry.terraform.io/hashicorp/null", + "name": "null", + "version_constraint": "3.1.1" + } + }, + "root_module": { + "resources": [ + { + "address": "null_resource.null_resource", + "mode": "managed", + "name": "null_resource", + "provider_config_key": "null", + "schema_version": 0, + "type": "null_resource" + } + ] + } + }, + "errored": false, + "format_version": "1.2", + "planned_values": { + "root_module": { + "resources": [ + { + "address": "null_resource.null_resource", + "mode": "managed", + "name": "null_resource", + "provider_name": "registry.terraform.io/hashicorp/null", + "schema_version": 0, + "sensitive_values": {}, + "type": "null_resource", + "values": { + "id": "3637779521417605172", + "triggers": null + } + } + ] + } + }, + "prior_state": { + "format_version": "1.0", + "values": { + "root_module": { + "resources": [ + { + "address": "null_resource.null_resource", + "mode": "managed", + "name": "null_resource", + "provider_name": "registry.terraform.io/hashicorp/null", + "schema_version": 0, + "sensitive_values": {}, + "type": "null_resource", + "values": { + "id": "3637779521417605172", + "triggers": null + } + } + ] + } + } + }, + "resource_changes": [ + { + "address": "null_resource.null_resource", + "change": { + "actions": [ + "no-op" + ], + "after": { + "id": "3637779521417605172", + "triggers": null + }, + "after_sensitive": {}, + "after_unknown": {}, + "before": { + "id": "3637779521417605172", + "triggers": null + }, + "before_sensitive": {} + }, + "mode": "managed", + "name": "null_resource", + "provider_name": "registry.terraform.io/hashicorp/null", + "type": "null_resource" + } + ] +} \ No newline at end of file diff --git a/testing/equivalence-tests/outputs/null_provider_update/state b/testing/equivalence-tests/outputs/null_provider_update/state new file mode 100644 index 0000000000..651823f4ed --- /dev/null +++ b/testing/equivalence-tests/outputs/null_provider_update/state @@ -0,0 +1,4 @@ +# null_resource.null_resource: +resource "null_resource" "null_resource" { + id = "3637779521417605172" +} diff --git a/testing/equivalence-tests/outputs/null_provider_update/state.json b/testing/equivalence-tests/outputs/null_provider_update/state.json new file mode 100644 index 0000000000..77ad52e453 --- /dev/null +++ b/testing/equivalence-tests/outputs/null_provider_update/state.json @@ -0,0 +1,22 @@ +{ + "format_version": "1.0", + "values": { + "root_module": { + "resources": [ + { + "address": "null_resource.null_resource", + "mode": "managed", + "name": "null_resource", + "provider_name": "registry.terraform.io/hashicorp/null", + "schema_version": 0, + "sensitive_values": {}, + "type": "null_resource", + "values": { + "id": "3637779521417605172", + "triggers": null + } + } + ] + } + } +} \ No newline at end of file From 3fc282bd1c5a364beb85ac0faa964f8fc1961a67 Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Wed, 20 Nov 2024 11:32:14 +0100 Subject: [PATCH 08/13] docs: update `dnf config-manager` usage (#35980) In Fedora Linux 41, which uses DNF5, backward compatibility with DNF4 was intentionally broken. The method for adding repositories via dnf config-manager has changed to use new sub-commands, such as addrepo. Signed-off-by: Bruno Schaatsbergen git@bschaatsbergen.com Signed-off-by: Bruno Schaatsbergen git@bschaatsbergen.com --- website/docs/cli/install/yum.mdx | 2 +- website/docs/language/stacks/reference/tfstacks-cli.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/cli/install/yum.mdx b/website/docs/cli/install/yum.mdx index b6b4b80970..96e557ee27 100644 --- a/website/docs/cli/install/yum.mdx +++ b/website/docs/cli/install/yum.mdx @@ -47,7 +47,7 @@ If you are using a DNF-based distribution, add the repository using ```bash sudo dnf install -y dnf-plugins-core -sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/$release/hashicorp.repo +sudo dnf config-manager addrepo --from-repofile=https://rpm.releases.hashicorp.com/$release/hashicorp.repo ``` In both cases, the Terraform package name is `terraform`. For example: diff --git a/website/docs/language/stacks/reference/tfstacks-cli.mdx b/website/docs/language/stacks/reference/tfstacks-cli.mdx index 8d7d8f6e22..48a4892f6c 100644 --- a/website/docs/language/stacks/reference/tfstacks-cli.mdx +++ b/website/docs/language/stacks/reference/tfstacks-cli.mdx @@ -54,7 +54,7 @@ Run the following commands to install the `terraform-stacks-cli` using Fedora. ```shell-session $ sudo dnf install -y dnf-plugins-core -$ sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/fedora/hashicorp.repo +$ sudo dnf config-manager addrepo --from-repofile=https://rpm.releases.hashicorp.com/fedora/hashicorp.repo $ sudo dnf -y install terraform-stacks-cli ``` From a628f8cbfc1386d69e711c1825acc322fe399970 Mon Sep 17 00:00:00 2001 From: Liam Cervante Date: Thu, 21 Nov 2024 11:04:30 +0100 Subject: [PATCH 09/13] Move mocking framework out of beta for 1.10 (#36057) --- website/docs/language/tests/mocking.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/language/tests/mocking.mdx b/website/docs/language/tests/mocking.mdx index b558c58d7b..2d42729e9d 100644 --- a/website/docs/language/tests/mocking.mdx +++ b/website/docs/language/tests/mocking.mdx @@ -6,7 +6,7 @@ description: >- # Mocks --> **Note**: Test mocking is available in Terraform v1.7.0 and later. This feature is in beta. +-> **Note**: Test mocking is available in Terraform v1.7.0 and later. Terraform lets you mock providers, resources, and data sources for your tests. This allows you to test parts of your module without creating infrastructure or requiring credentials. In a Terraform test, a mocked provider or resource will generate fake data for all computed attributes that would normally be provided by the underlying provider APIs. From ccdd825dbf7e1c3c67dcc2434682975995a9950e Mon Sep 17 00:00:00 2001 From: Anteneh Metaferia Date: Thu, 21 Nov 2024 11:07:02 +0100 Subject: [PATCH 10/13] feat: add NetRC support to the provider installer (#35843) --- internal/providercache/package_install.go | 56 +++++++++-------------- 1 file changed, 21 insertions(+), 35 deletions(-) diff --git a/internal/providercache/package_install.go b/internal/providercache/package_install.go index 0c43068bca..762b149adb 100644 --- a/internal/providercache/package_install.go +++ b/internal/providercache/package_install.go @@ -6,8 +6,7 @@ package providercache import ( "context" "fmt" - "io/ioutil" - "net/http" + "net/url" "os" "path/filepath" @@ -26,54 +25,41 @@ import ( var unzip = getter.ZipDecompressor{} func installFromHTTPURL(ctx context.Context, meta getproviders.PackageMeta, targetDir string, allowedHashes []getproviders.Hash) (*getproviders.PackageAuthenticationResult, error) { - url := meta.Location.String() + urlStr := meta.Location.String() // When we're installing from an HTTP URL we expect the URL to refer to // a zip file. We'll fetch that into a temporary file here and then // delegate to installFromLocalArchive below to actually extract it. - // (We're not using go-getter here because its HTTP getter has a bunch - // of extraneous functionality we don't need or want, like indirection - // through X-Terraform-Get header, attempting partial fetches for - // files that already exist, etc.) + httpGetter := getter.HttpGetter{ + Client: httpclient.New(), + Netrc: true, + XTerraformGetDisabled: true, + } - httpClient := httpclient.New() - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) + urlObj, err := url.Parse(urlStr) if err != nil { + // We don't expect to get non-HTTP locations here because we're + // using the registry source, so this seems like a bug in the + // registry source. return nil, fmt.Errorf("invalid provider download request: %s", err) } - resp, err := httpClient.Do(req) - if err != nil { - if ctx.Err() == context.Canceled { - // "context canceled" is not a user-friendly error message, - // so we'll return a more appropriate one here. - return nil, fmt.Errorf("provider download was interrupted") - } - return nil, fmt.Errorf("%s: %w", getproviders.HostFromRequest(req), err) - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("unsuccessful request to %s: %s", url, resp.Status) - } - - f, err := ioutil.TempFile("", "terraform-provider") + f, err := os.CreateTemp("", "terraform-provider") if err != nil { - return nil, fmt.Errorf("failed to open temporary file to download from %s: %w", url, err) + return nil, fmt.Errorf("failed to open temporary file to download from %s: %w", urlStr, err) } defer f.Close() defer os.Remove(f.Name()) - // We'll borrow go-getter's "cancelable copy" implementation here so that - // the download can potentially be interrupted partway through. - n, err := getter.Copy(ctx, f, resp.Body) - if err == nil && n < resp.ContentLength { - err = fmt.Errorf("incorrect response size: expected %d bytes, but got %d bytes", resp.ContentLength, n) - } + archiveFilename := f.Name() + err = httpGetter.GetFile(archiveFilename, urlObj) if err != nil { - return nil, err + if ctx.Err() == context.Canceled { + // "context canceled" is not a user-friendly error message, + // so we'll return a more appropriate one here. + return nil, fmt.Errorf("provider download was interrupted") + } + return nil, fmt.Errorf("%s: %w", urlObj.Host, err) } - - archiveFilename := f.Name() localLocation := getproviders.PackageLocalArchive(archiveFilename) var authResult *getproviders.PackageAuthenticationResult From af99a73b5468966300f2e2fe465a5d67f5848c00 Mon Sep 17 00:00:00 2001 From: Liam Cervante Date: Thu, 21 Nov 2024 11:12:39 +0100 Subject: [PATCH 11/13] Update docs for .netrc integration with provider downloads (#36022) * Update docs for .netrc integration with provider downloads * Apply suggestions from code review Co-authored-by: Rose M Koron <32436232+rkoron007@users.noreply.github.com> * tidy up after weird auto-merge --------- Co-authored-by: Rose M Koron <32436232+rkoron007@users.noreply.github.com> --- website/docs/language/providers/index.mdx | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/website/docs/language/providers/index.mdx b/website/docs/language/providers/index.mdx index 621a4854ee..49b68ad6b6 100644 --- a/website/docs/language/providers/index.mdx +++ b/website/docs/language/providers/index.mdx @@ -93,6 +93,27 @@ installing providers. > **Hands-on:** Try the [Lock and Upgrade Provider Versions](/terraform/tutorials/configuration-language/provider-versioning?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial. +### Private Providers + +If you are using a provider that is not in a Hashicorp-hosted registry, you may +need to attach additional credentials to your requests to external registries. +You do not need these credentials if your provider is in the Terraform public +registry or the HCP Terraform private registry. + +By default, Terraform only authenticates the opening request from a provider to +the registry. The registry responds with +[follow-up URLs](/terraform/internals/provider-registry-protocol#find-a-provider-package) +that Terraform makes requests to, such as telling Terraform to download the +provider or the `SHASUMS` file. Hashicorp-hosted registries do not require +additional authentication for these follow-up requests. If your registry does +require additional credentials for follow-up requests, you can use a `.netrc` +file to provide those credentials. + +By default, Terraform searches for the `.netrc` file in your `HOME` directory. +However, you can override the default filesystem location by setting the `NETRC` +environment variable. For information on the format of`.netrc`, refer to the +[`curl` documentation](https://everything.curl.dev/usingcurl/netrc). + ## How to Find Providers To find providers for the infrastructure platforms you use, browse From 291c1ad4ada7754095d59b535dc8518eeef0e3f1 Mon Sep 17 00:00:00 2001 From: Liam Cervante Date: Thu, 21 Nov 2024 11:29:51 +0100 Subject: [PATCH 12/13] Update CHANGELOG.md (#36070) --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae928c8fff..b35d341bea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## 1.11.0 (Unreleased) +ENHANCEMENTS: + +- `init`: Provider installation will utilise credentials configured in a `.netrc` file for the download and shasum URLs returned by provider registries. ([https://github.com/hashicorp/terraform/pull/35843](35843)) + EXPERIMENTS: Experiments are only enabled in alpha releases of Terraform CLI. The following features are not yet available in stable releases. From b4a634ced88673d4d208ddee41f39666f51cd133 Mon Sep 17 00:00:00 2001 From: nimzo6689 Date: Thu, 21 Nov 2024 19:34:35 +0900 Subject: [PATCH 13/13] Remove Interpolation-only expressions from website/docs files (#36065) * Remove Interpolation-only expressions from website/docs files Interpolation-only expressions are deprecated in Terraform v0.12.14 See. https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.10.0/docs/rules/terraform_deprecated_interpolation.md * Revert whitespace trimming at the end of lines * Preserve interpolation-only expressions for JSON * Preserve interpolation-only expressions for < 0.11 samples * Remove Interpolation-only expressions from website/docs files --- website/docs/cli/commands/import.mdx | 4 ++-- website/docs/language/backend/s3.mdx | 2 +- website/docs/language/expressions/dynamic-blocks.mdx | 2 +- website/docs/language/modules/develop/providers.mdx | 4 ++-- .../docs/language/resources/provisioners/connection.mdx | 8 ++++---- website/docs/language/state/workspaces.mdx | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/website/docs/cli/commands/import.mdx b/website/docs/cli/commands/import.mdx index 59c6d3af42..6f26f2d6a5 100644 --- a/website/docs/cli/commands/import.mdx +++ b/website/docs/cli/commands/import.mdx @@ -108,8 +108,8 @@ variable "access_key" {} variable "secret_key" {} provider "aws" { - access_key = "${var.access_key}" - secret_key = "${var.secret_key}" + access_key = var.access_key + secret_key = var.secret_key } ``` diff --git a/website/docs/language/backend/s3.mdx b/website/docs/language/backend/s3.mdx index e68514c623..9cb3269bd4 100644 --- a/website/docs/language/backend/s3.mdx +++ b/website/docs/language/backend/s3.mdx @@ -454,7 +454,7 @@ provider "aws" { # environment or the global credentials file. assume_role = { - role_arn = "${var.workspace_iam_roles[terraform.workspace]}" + role_arn = var.workspace_iam_roles[terraform.workspace] } } ``` diff --git a/website/docs/language/expressions/dynamic-blocks.mdx b/website/docs/language/expressions/dynamic-blocks.mdx index dbcc3ab1e9..ce30ce9549 100644 --- a/website/docs/language/expressions/dynamic-blocks.mdx +++ b/website/docs/language/expressions/dynamic-blocks.mdx @@ -30,7 +30,7 @@ special `dynamic` block type, which is supported inside `resource`, `data`, ```hcl resource "aws_elastic_beanstalk_environment" "tfenvtest" { name = "tf-test-name" - application = "${aws_elastic_beanstalk_application.tftest.name}" + application = aws_elastic_beanstalk_application.tftest.name solution_stack_name = "64bit Amazon Linux 2018.03 v2.11.4 running Go 1.12.6" dynamic "setting" { diff --git a/website/docs/language/modules/develop/providers.mdx b/website/docs/language/modules/develop/providers.mdx index 6b4a7594cd..df1a88df83 100644 --- a/website/docs/language/modules/develop/providers.mdx +++ b/website/docs/language/modules/develop/providers.mdx @@ -334,7 +334,7 @@ provider "aws" { provider "google" { alias = "usw1" - credentials = "${file("account.json")}" + credentials = file("account.json") project = "my-project-id" region = "us-west1" zone = "us-west1-a" @@ -342,7 +342,7 @@ provider "google" { provider "google" { alias = "usw2" - credentials = "${file("account.json")}" + credentials = file("account.json") project = "my-project-id" region = "us-west2" zone = "us-west2-a" diff --git a/website/docs/language/resources/provisioners/connection.mdx b/website/docs/language/resources/provisioners/connection.mdx index e526083665..0b3e29e44c 100644 --- a/website/docs/language/resources/provisioners/connection.mdx +++ b/website/docs/language/resources/provisioners/connection.mdx @@ -59,8 +59,8 @@ provisioner "file" { connection { type = "ssh" user = "root" - password = "${var.root_password}" - host = "${var.host}" + password = var.root_password + host = var.host } } @@ -72,8 +72,8 @@ provisioner "file" { connection { type = "winrm" user = "Administrator" - password = "${var.admin_password}" - host = "${var.host}" + password = var.admin_password + host = var.host } } ``` diff --git a/website/docs/language/state/workspaces.mdx b/website/docs/language/state/workspaces.mdx index 56a5bd0ec7..88f7515248 100644 --- a/website/docs/language/state/workspaces.mdx +++ b/website/docs/language/state/workspaces.mdx @@ -53,7 +53,7 @@ to spin up smaller cluster sizes. For example: ```hcl resource "aws_instance" "example" { - count = "${terraform.workspace == "default" ? 5 : 1}" + count = terraform.workspace == "default" ? 5 : 1 # ... other arguments }