Skip to content

Commit

Permalink
Merge branch 'main' into RK/write-only-GA
Browse files Browse the repository at this point in the history
  • Loading branch information
rkoron007 authored Feb 24, 2025
2 parents 9e66122 + c3b339e commit 8d59091
Show file tree
Hide file tree
Showing 37 changed files with 762 additions and 467 deletions.
5 changes: 5 additions & 0 deletions .changes/v1.11/ENHANCEMENTS-20250219-094101.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: ENHANCEMENTS
body: 'backend/oss: Add new argument tablestore_instance_name used in VPC context'
time: 2025-02-19T09:41:01.733881+08:00
custom:
Issue: "36253"
38 changes: 36 additions & 2 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ To report a bug, an enhancement proposal, or give any other product feedback, pl
- [Maintainers](#maintainers)
- [Pull Request Lifecycle](#pull-request-lifecycle)
- [Getting Your Pull Requests Merged Faster](#getting-your-pull-requests-merged-faster)
- [Changelog entries](#changelog-entries)
- [Create a change file using `changie`](#create-a-change-file-using-changie)
- [Backport a PR to a past release](#backport-a-pr-to-a-past-release)
- [PR Checks](#pr-checks)
- [Terraform CLI/Core Development Environment](#terraform-clicore-development-environment)
- [Acceptance Tests: Testing interactions with external services](#acceptance-tests-testing-interactions-with-external-services)
Expand Down Expand Up @@ -121,8 +124,7 @@ If an an unmaintained area of code interests you and you'd like to become a main

1. You are welcome to submit a [draft pull request](https://github.blog/2019-02-14-introducing-draft-pull-requests/) for commentary or review before it is fully completed. It's also a good idea to include specific questions or items you'd like feedback on.
2. Once you believe your pull request is ready to be merged you can create your pull request.
3. If your change is user-facing, add a short description in a changelog entry.
You can use `npx changie new` to create a new changelog entry or manually create a new file in the .changes/unreleased directory.
3. If your change is user-facing, add a short description in a [changelog entry](#changelog-entries).
4. When time permits Terraform's core team members will look over your contribution and either merge, or provide comments letting you know if there is anything left to do. It may take some time for us to respond. We may also have questions that we need answered about the code, either because something doesn't make sense to us or because we want to understand your thought process. We kindly ask that you do not target specific team members.
5. If we have requested changes, you can either make those changes or, if you disagree with the suggested changes, we can have a conversation about our reasoning and agree on a path forward. This may be a multi-step process. Our view is that pull requests are a chance to collaborate, and we welcome conversations about how to do things better. It is the contributor's responsibility to address any changes requested. While reviewers are happy to give guidance, it is unsustainable for us to perform the coding work necessary to get a PR into a mergeable state.
6. Once all outstanding comments and checklist items have been addressed, your contribution will be merged! Merged PRs may or may not be included in the next release based on changes the Terraform teams deems as breaking or not. The core team takes care of updating the [CHANGELOG.md](https://github.com/hashicorp/terraform/blob/main/CHANGELOG.md) as they merge.
Expand All @@ -140,12 +142,44 @@ If we request changes, try to make those changes in a timely manner. Otherwise,

Even with everyone making their best effort to be responsive, it can be time-consuming to get a PR merged. It can be frustrating to deal with the back-and-forth as we make sure that we understand the changes fully. Please bear with us, and please know that we appreciate the time and energy you put into the project.

#### Changelog entries

If your PR's changes are not user-facing add the label `no-changelog-needed`. If this label isn't present and your PR doesn't include any change files a Github Action workflow will prompt you to add whichever is needed.

If your PR's changes are user-facing then you will need to add a change file in your PR. See the next section for how to create one. The change file will need to be created in the `.changes/v1.XX/` folder that matches the version number present in [version/VERSION on the main branch](https://github.com/hashicorp/terraform/blob/main/version/VERSION).

This is different if you are backporting your changes to an earlier release version. In that case, put the change file in the `.changes/v1.XX/` folder for the earliest version that the change is being backported into. For example if a PR was labelled 1.11-backport and 1.10-backport then the change file should be created in the `.changes/v1.10/` folder only.


#### Create a change file using `changie`

If your change is user-facing you can use `npx changie new` to create a new changelog entry via your terminal. The command is interactive and you will need to: select which kind of change you're introducing, provide a short description, and enter either the number of the GitHub issue your PR closes or your PR's number.

Make sure to select the correct kind of change:


| Change kind | When to use |
|------------------|-------------|
| NEW FEATURES | Use this if you've added new, separate functionality to Terraform. For example, introduction of ephemeral resources. |
| ENHANCEMENTS | Use this if you've improved existing functionality in Terraform. Examples include: adding a new field to a remote-state backend, or adding a new environment variable to use when configuring Terraform. |
| BUG FIXES | Use this if you've fixed a user-facing issue. Examples include: crash fixes, improvements to error feedback, regression fixes. |
| NOTES | This is used for changes that are unlikely to cause user-facing issues but might have edge cases. For example, changes to how the Terraform binary is built. |
| UPGRADE NOTES | Use this if you've introduced a change that forces users to take action when upgrading, or changes Terraform's behaviour notably. For example, deprecating a field on a remote-state backend or changing the output of Terraform operations. |
| BREAKING CHANGES | Use this if you've introduced a change that could make a valid Terraform configuration stop working after a user upgrades Terraform versions. This might be paired with an upgrade note change file. Examples include: removing a field on a remote-state backend, changing a builtin function's behavior, making validation stricter. |

#### Backport a PR to a past release

PRs can be backported to previous release version as part of preparing a patch release. For example, a fix for a bug could be merged into main but also backported to one or two previous minor versions.

If you want to backport your PR then the PR needs to have one or more [backport labels](https://github.com/hashicorp/terraform/labels?q=backport) added. The PR reviewer will then ensure that the PR is merged into those versions' release branches, as well as merged into `main`.

### PR Checks

The following checks run when a PR is opened:

- Contributor License Agreement (CLA): If this is your first contribution to Terraform you will be asked to sign the CLA.
- Tests: tests include unit tests and acceptance tests, and all tests must pass before a PR can be merged.
- Change files: PRs that include user-facing changes should include change files (see [Pull Request Lifecycle](#pull-request-lifecycle)). Automation will verify if PRs are labelled correctly and/or contain appropriate change files.
- Vercel: this is an internal tool that does not run correctly for external contributors. We are aware of this and work around it for external contributions.

----
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ vendor/

# Coverage
coverage.txt

# IDEs
.vscode/
27 changes: 27 additions & 0 deletions docs/debugging-configs/vscode/debug-automated-tests/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"version": "0.2.0",
"configurations": [
{
// Highlight a test's name with your cursor and run this debugger configuration
// from the debugger tools in the left-side Activity Bar.
// This will result in the equivalent of this command being run using the debugger:
// `go test -v -run ^<selected text>$ <the current opened file's folder path>`
"name": "Run selected test",
"request": "launch",
"type": "go",
"args": [
"-test.v",
"-test.run",
"^${selectedText}$"
],
// Environment variables can be set from a file or as key-value pairs in the configuration.
// "env": {
// "MY_ENV": "my-value",
// },
// "envFile": "./vscode/private.env",
"mode": "auto",
"program": "${fileDirname}",
"showLog": true // dlv's logs
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"version": "0.2.0",
"configurations": [
{
// Runs Terraform using the Terraform configuration specified via the chdir argument
"name": "Run Terraform in debug mode",
"request": "launch",
"type": "go",
"args": [
"-chdir=<absolute path to a Terraform configuration>",
// Change this array to perform different terraform commands with different arguments.
"plan",
"-var='name=value'"
],
// "cwd": "<absolute path to a Terraform configuration>", // An alternative to using the -chdir global flag above.
// Environment variables can be set from a file or as key-value pairs in the configuration.
// "env": {
// "MY_ENV": "my-value",
// },
// "envFile": "./vscode/private.env",
"mode": "debug",
"program": "${workspaceFolder}",
"console": "integratedTerminal", // allows responding to y/n in terminal, e.g. in apply command.
"showLog": false // dlv's logs
}
]
}
File renamed without changes.
78 changes: 71 additions & 7 deletions docs/debugging.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,45 @@
# How to Debug Terraform

Contents:
- [Debugging automated tests](#debugging-automated-tests)
- [Debugging automated tests in VSCode](#debugging-automated-tests-in-vscode)
- [Debugging Terraform operations that use real Terraform configurations](#debugging-terraform-operations-that-use-real-terraform-configurations)
- [Launch Terraform with the `dlv` CLI tool](#launch-terraform-with-the-dlv-cli-tool)
- [Launch Terraform with VS Code's debugging tool](#launch-terraform-with-vs-codes-debugging-tool)


As Terraform is written in Go you may use [Delve](https://github.com/go-delve/delve) to debug it.

## 1. Compile & Start Debug Server
GoLand includes [debugging features](https://www.jetbrains.com/help/go/debugging-code.html), and the [Go extension for VS Code](https://code.visualstudio.com/docs/languages/go#_debugging) makes it easy to use Delve when debugging Go codebases in VS Code.

## Debugging automated tests

Debugging an automated test is often the most straightforward workflow for debugging a section of the codebase. For example, the Go extension for VS Code](https://code.visualstudio.com/docs/languages/go#_debugging) adds `run test | debug test` options above all tests in a `*_test.go` file. These allow debugging without any prior configuration.

### Debugging automated tests in VSCode

As described above, debugging tests in VS Code is easily achieved through the Go extension.

If you need more control over how tests are run while debugging, e.g. environment variable values, look at the [example debugger launch configuration 'Run selected test'](./debugging-configs/vscode/debug-automated-tests/launch.json). You can adapt this example to create your own [launch configuration file](https://code.visualstudio.com/docs/editor/debugging#_launch-configurations).

When using this launch configuration you must highlight a test's name before starting the debugger:

<p align="center">
<img width="75%" alt="Debugging a single test using the example 'Run selected test' debugger configuration shared in this repository" src="./images/vscode-debugging-test.png"/>
</p>


## Debugging Terraform operations that use real Terraform configurations

### Launch Terraform with the `dlv` CLI tool

In this workflow you:
* Build Terraform using compiler flags.
* Start a debug server with a command containing the terraform command you want to debug.
* This command is run in the working directory that contains your Terraform configuration.
* Connect to the debug server to monitor progress through breakpoints.

#### 1. Compile & Start Debug Server

One way to do it is to compile a binary with the [appropriate compiler flags](https://pkg.go.dev/cmd/compile#hdr-Command_Line):

Expand All @@ -13,21 +50,48 @@ go install -gcflags="all=-N -l"
This enables you to then execute the compiled binary via Delve, pass any arguments and spin up a debug server which you can then connect to:

```sh
dlv exec $GOBIN/terraform --headless --listen :2345 --log -- apply
# Update the path to the terraform binary if your install directory is influenced by $GOPATH or $GOBIN
dlv exec $HOME/go/bin/terraform --headless --listen :2345 --log -- apply
```

## 2a. Connect via CLI
#### 2a. Connect via CLI

You may connect to the headless debug server via Delve CLI

```sh
dlv connect :2345
```

## 2b. Connect from VS Code
#### 2b. Connect from VS Code

The repository provides [an example 'Connect to dlv server' launch configuration](./debugging-configs/vscode/launch-via-cli/launch.json), making it possible to use VS Code's native debugging integration via the [Go extension for VS Code](https://code.visualstudio.com/docs/languages/go#_debugging):

<p align="center">
<img width="75%" alt="vscode debugger" src="./images/vscode-debugging.png"/>
</p>


### Launch Terraform with VS Code's debugging tool

In this workflow you:
* Update the debugger's launch configuration to point at the directory containing your Terraform configuration.
* Start the debugger through VS Code and monitor progress through breakpoints.

#### 1. Update the debugger's launch configuration

Look at the [example debugger launch configuration 'Run Terraform in debug mode'](./debugging-configs/vscode/launch-from-vscode-debugger/launch.json). You can adapt this example to create your own [launch configuration file](https://code.visualstudio.com/docs/editor/debugging#_launch-configurations).

To use this launch configuration:
* Prepare a local Terraform project.
* Get the absolute path to that directory.
* Update the launch configuration to use that path, either in the `-chdir` argument or as a `cwd` attribute in the launch configuration.
* Make sure the `args` array's element reflect the command you'd like to debug.
* Provide any required environment variables through the `env` or `envFile` attributes.

#### 2. Run the launch configuration in VS Code

The repository provides a launch configuration, making it possible to use VS Code's native debugging integration:
Navigate to the Run and Debug view in the left-side Activity Bar. After selecting the `Run Terraform in debug mode` configuration in the Run and Debug view from the left-side, press the green arrow.

![vscode debugger](./images/vscode-debugging.png)
This is equivalent to running a Terraform CLI command in the local Terraform project's directory. For example, if you run and debug a plan command that saves a plan file, that plan file will be created.

Note that this debugging workflow is different from the test-based one, which itself shouldn't require any of the above steps above nor the mentioned launch configuration. Meaning, that if you already have a test that hits the right lines of code you want to be debugging, or you can write one, then that may be an easier workflow.
This workflow is useful if you need to set up a complicated prior state to replicate a bug or if you want to debug code behaviour given a specific configuration.
Binary file added docs/images/vscode-debugging-test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 8 additions & 21 deletions internal/backend/backendbase/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,16 @@ func TestBase_coerceError(t *testing.T) {
// This is incorrect because the schema wants a string
"foo": cty.MapValEmpty(cty.String),
}))
// We'll use the "RPC" representation of the diagnostics just because
// it's convenient for comparing without any unusual cmp options.
gotDiags := diags.InConfigBody(body, "").ForRPC()
gotDiags := diags.InConfigBody(body, "")
var wantDiags tfdiags.Diagnostics
wantDiags = wantDiags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid backend configuration",
Detail: "The backend configuration is incorrect: .foo: string required.",
Subject: &hcl.Range{Filename: "MockExprLiteral"},
})
wantDiags = wantDiags.ForRPC()
if diff := cmp.Diff(wantDiags, gotDiags); diff != "" {
t.Errorf("wrong diagnostics\n%s", diff)
}

tfdiags.AssertDiagnosticsMatch(t, gotDiags, wantDiags)
})
}

Expand Down Expand Up @@ -166,20 +162,16 @@ func TestBase_deprecatedArg(t *testing.T) {
_, diags := b.PrepareConfig(cty.ObjectVal(map[string]cty.Value{
"deprecated": cty.StringVal("hello"),
}))
// We'll use the "RPC" representation of the diagnostics just because
// it's convenient for comparing without any unusual cmp options.
gotDiags := diags.InConfigBody(body, "").ForRPC()

gotDiags := diags.InConfigBody(body, "")
var wantDiags tfdiags.Diagnostics
wantDiags = wantDiags.Append(&hcl.Diagnostic{
Severity: hcl.DiagWarning,
Summary: "Deprecated provider argument",
Detail: "The argument .deprecated is deprecated. Refer to the backend documentation for more information.",
Subject: &hcl.Range{Filename: "MockExprLiteral"},
})
wantDiags = wantDiags.ForRPC()
if diff := cmp.Diff(wantDiags, gotDiags); diff != "" {
t.Errorf("wrong diagnostics\n%s", diff)
}
tfdiags.AssertDiagnosticsMatch(t, wantDiags, gotDiags)
})
t.Run("nested deprecated", func(t *testing.T) {
_, diags := b.PrepareConfig(cty.ObjectVal(map[string]cty.Value{
Expand All @@ -192,9 +184,7 @@ func TestBase_deprecatedArg(t *testing.T) {
}),
}),
}))
// We'll use the "RPC" representation of the diagnostics just because
// it's convenient for comparing without any unusual cmp options.
gotDiags := diags.InConfigBody(body, "").ForRPC()
gotDiags := diags.InConfigBody(body, "")
var wantDiags tfdiags.Diagnostics
wantDiags = wantDiags.Append(&hcl.Diagnostic{
Severity: hcl.DiagWarning,
Expand All @@ -208,10 +198,7 @@ func TestBase_deprecatedArg(t *testing.T) {
Detail: "The argument .nested[1].deprecated is deprecated. Refer to the backend documentation for more information.",
Subject: &hcl.Range{Filename: "MockExprLiteral"},
})
wantDiags = wantDiags.ForRPC()
if diff := cmp.Diff(wantDiags, gotDiags); diff != "" {
t.Errorf("wrong diagnostics\n%s", diff)
}
tfdiags.AssertDiagnosticsMatch(t, wantDiags, gotDiags)
})
}

Expand Down
13 changes: 11 additions & 2 deletions internal/backend/remote-state/oss/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@ func New() backend.Backend {
},
Default: "terraform.tfstate",
},
"tablestore_instance_name": {
Type: schema.TypeString,
Optional: true,
Description: "The instance name of tableStore table belongs",
Default: "",
},

"tablestore_table": {
Type: schema.TypeString,
Expand Down Expand Up @@ -414,13 +420,16 @@ func (b *Backend) configure(ctx context.Context) error {
client, err := oss.New(endpoint, accessKey, secretKey, options...)
b.ossClient = client
otsEndpoint := d.Get("tablestore_endpoint").(string)
otsInstanceName := d.Get("tablestore_instance_name").(string)
if otsEndpoint != "" {
if !strings.HasPrefix(otsEndpoint, "http") {
otsEndpoint = fmt.Sprintf("%s://%s", schma, otsEndpoint)
}
b.otsEndpoint = otsEndpoint
parts := strings.Split(strings.TrimPrefix(strings.TrimPrefix(otsEndpoint, "https://"), "http://"), ".")
b.otsClient = tablestore.NewClientWithConfig(otsEndpoint, parts[0], accessKey, secretKey, securityToken, tablestore.NewDefaultTableStoreConfig())
if otsInstanceName == "" {
otsInstanceName = strings.Split(strings.TrimPrefix(strings.TrimPrefix(otsEndpoint, "https://"), "http://"), ".")[0]
}
b.otsClient = tablestore.NewClientWithConfig(otsEndpoint, otsInstanceName, accessKey, secretKey, securityToken, tablestore.NewDefaultTableStoreConfig())
}
b.otsTable = d.Get("tablestore_table").(string)

Expand Down
Loading

0 comments on commit 8d59091

Please sign in to comment.