Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
202a208
WIP testing new hyok customer key version resource
dominic-retli-hashi Sep 9, 2025
4060a6a
added data source for hyok encrypted data key and hyok customer key v…
dominic-retli-hashi Sep 12, 2025
81ad65c
maded tests generic and dependent on env var
dominic-retli-hashi Sep 15, 2025
34dae45
added mention of the env vars needed for the hyok data source tests i…
dominic-retli-hashi Sep 15, 2025
8b846dc
updated change log
dominic-retli-hashi Sep 15, 2025
2713372
Merge branch 'main' into dominicretli/TF-28674/hyok-data-objects
dominic-retli-hashi Sep 15, 2025
5a1c9b2
Merge remote-tracking branch 'origin/main' into dominicretli/TF-28674…
dominic-retli-hashi Sep 17, 2025
49d4a3a
Added website docs for hyok data sources
dominic-retli-hashi Sep 18, 2025
6abdd35
Added workspaces secured, general cleanup
dominic-retli-hashi Sep 18, 2025
8457a54
updated docs
dominic-retli-hashi Sep 18, 2025
66f2a61
test cleanup
dominic-retli-hashi Sep 18, 2025
44add6a
misc cleanup
dominic-retli-hashi Sep 24, 2025
afa401b
Merge branch 'feature/hyok' into dominicretli/TF-28674/hyok-data-objects
dominic-retli-hashi Sep 24, 2025
9a469a4
renamed variable for lint
dominic-retli-hashi Sep 24, 2025
a7622dd
Merge branch 'dominicretli/TF-28674/hyok-data-objects' of github.com:…
dominic-retli-hashi Sep 24, 2025
91036d7
[TF-28672] Add Vault, AWS, GCP, and Azure OIDC configuration resource…
helenjw Sep 25, 2025
c83b4ba
[TF-28671] Add HYOK configuration resources (#1841)
helenjw Sep 25, 2025
8a2e80c
Merge branch 'feature/hyok' into dominicretli/TF-28674/hyok-data-objects
iuri-slywitch-hashicorp Sep 26, 2025
f192017
Merge pull request #1842 from hashicorp/dominicretli/TF-28674/hyok-da…
dominic-retli-hashi Sep 26, 2025
1609917
Add skipUnlessHYOKEnabled check before performing tests in data_sourc…
helenjw Sep 30, 2025
550a5ba
Update CHANGELOG.md formatting
helenjw Oct 1, 2025
12c21fd
[TF-28673] Adding HYOK related attributes to Organizations and Worksp…
iuri-slywitch-hashicorp Oct 7, 2025
3f87b7d
Merge branch 'main' into feature/hyok
iuri-slywitch-hashicorp Oct 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
## Unreleased
FEATURES:
* **New resource**: `r/tfe_vault_oidc_configuration` for managing Vault OIDC configurations. by @helenjw [#1835](https://github.com/hashicorp/terraform-provider-tfe/pull/1835)
* **New resource**: `r/tfe_aws_oidc_configuration` for managing AWS OIDC configurations. by @helenjw [#1835](https://github.com/hashicorp/terraform-provider-tfe/pull/1835)
* **New resource**: `r/tfe_gcp_oidc_configuration` for managing GCP OIDC configurations. by @helenjw [#1835](https://github.com/hashicorp/terraform-provider-tfe/pull/1835)
* **New resource**: `r/tfe_azure_oidc_configuration` for managing Azure OIDC configurations. by @helenjw. [#1835](https://github.com/hashicorp/terraform-provider-tfe/pull/1835)
* **New resource**: `r/tfe_hyok_configuration` for managing HYOK configurations. by @helenjw [#1835](https://github.com/hashicorp/terraform-provider-tfe/pull/1841)
* **New Data Source:** `d/hyok_customer_key_version` is a new data source for finding HYOK customer key versions. by @dominicretli [#1842](https://github.com/hashicorp/terraform-provider-tfe/pull/1842)
* **New Data Source:** `d/hyok_encrypted_data_key` is a new data source for finding HYOK encrypted data keys. by @dominicretli [#1842](https://github.com/hashicorp/terraform-provider-tfe/pull/1842)
* `r/tfe_organization`: Adds the `enforce_hyok` boolean attribute, by @iuri-slywitch-hashicorp.
* `d/tfe_organization`: Adds the `enforce_hyok` boolean attribute, by @iuri-slywitch-hashicorp.
* `r/tfe_workspace`: Adds the `hyok_enabled` read-only boolean attribute, by @iuri-slywitch-hashicorp.
* `d/tfe_workspace`: Adds the `hyok_enabled` read-only boolean attribute, by @iuri-slywitch-hashicorp.

## v0.70.0

Expand Down
3 changes: 3 additions & 0 deletions docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ these values with the environment variables specified below:
1. `RUN_TASKS_HMAC` - The optional HMAC Key that should be used for Run Task operations. The default is no key.
1. `GITHUB_APP_INSTALLATION_ID` - GitHub App installation internal id in the format `ghain-xxxxxxx`. Required for running any tests that use GitHub App VCS (workspace, policy sets, registry module).
1. `GITHUB_APP_INSTALLATION_NAME` - GitHub App installation name. Required for running tfe_github_app_installation data source test.
1. `ENABLE_HYOK` - Set `ENABLE_HYOK=1` to enable HYOK-related tests.
1. `HYOK_ENCRYPTED_DATA_KEY_ID` - HYOK encrypted data key id. Required for running hyok_encrypted_data_key data source test.
1. `HYOK_CUSTOMER_KEY_VERSION_ID` - HYOK customer key version id. Required for running hyok_customer_key_version data source test.

**Note:** In order to run integration tests for **Paid** features you will need a token `TFE_TOKEN` with HCP Terraform or Terraform Enterprise administrator privileges, otherwise the attempt to upgrade an organization's feature set will fail.

Expand Down
115 changes: 115 additions & 0 deletions internal/provider/data_source_hyok_customer_key_version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package provider

import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"time"
)

var (
_ datasource.DataSource = &dataSourceHYOKCustomerKeyVersion{}
_ datasource.DataSourceWithConfigure = &dataSourceHYOKCustomerKeyVersion{}
)

func NewHYOKCustomerKeyVersionDataSource() datasource.DataSource {
return &dataSourceHYOKCustomerKeyVersion{}
}

type dataSourceHYOKCustomerKeyVersion struct {
config ConfiguredClient
}

type HYOKCustomerKeyVersionDataSourceModel struct {
ID types.String `tfsdk:"id"`
Status types.String `tfsdk:"status"`
Error types.String `tfsdk:"error"`
KeyVersion types.String `tfsdk:"key_version"`
CreatedAt types.String `tfsdk:"created_at"`
WorkspacesSecured types.Int64 `tfsdk:"workspaces_secured"`
}

func (d *dataSourceHYOKCustomerKeyVersion) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
if req.ProviderData == nil {
return
}

client, ok := req.ProviderData.(ConfiguredClient)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected tfe.ConfiguredClient, got %T. This is a bug in the tfe provider, so please report it on GitHub.", req.ProviderData),
)

return
}
d.config = client
}

func (d *dataSourceHYOKCustomerKeyVersion) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_hyok_customer_key_version"
}

func (d *dataSourceHYOKCustomerKeyVersion) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "This data source can be used to retrieve a HYOK customer key version.",
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "The ID of the HYOK customer key version.",
Required: true,
},
"status": schema.StringAttribute{
Description: "The status of the HYOK customer key version.",
Computed: true,
},
"error": schema.StringAttribute{
Description: "Any error message associated with the HYOK customer key version.",
Computed: true,
},
"key_version": schema.StringAttribute{
Description: "The version number of the customer key version.",
Computed: true,
},
"workspaces_secured": schema.Int64Attribute{
Description: "The number workspaces secured by this customer key version.",
Computed: true,
},
"created_at": schema.StringAttribute{
Description: "The timestamp when the key version was created.",
Computed: true,
},
},
}
}

func (d *dataSourceHYOKCustomerKeyVersion) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data HYOKCustomerKeyVersionDataSourceModel

// Read Terraform configuration data into the model
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}

// Make API call to fetch the HYOK customer key version
keyVersion, err := d.config.Client.HYOKCustomerKeyVersions.Read(ctx, data.ID.ValueString())
if err != nil {
resp.Diagnostics.AddError("Unable to read HYOK customer key version", err.Error())
return
}

// Set the computed attributes from the API response
data.Status = types.StringValue(string(keyVersion.Status))
data.KeyVersion = types.StringValue(keyVersion.KeyVersion)
data.CreatedAt = types.StringValue(keyVersion.CreatedAt.Format(time.RFC3339))
data.WorkspacesSecured = types.Int64Value(int64(keyVersion.WorkspacesSecured))
data.Error = types.StringValue(keyVersion.Error)

// Save data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
42 changes: 42 additions & 0 deletions internal/provider/data_source_hyok_customer_key_version_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package provider

import (
"os"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

func TestAccTFEHYOKCustomerKeyVersionDataSource_basic(t *testing.T) {
skipUnlessHYOKEnabled(t)

hyokCustomerKeyVersionID := os.Getenv("HYOK_CUSTOMER_KEY_VERSION_ID")
if hyokCustomerKeyVersionID == "" {
t.Skip("HYOK_CUSTOMER_KEY_VERSION_ID environment variable must be set to run this test")
}

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccMuxedProviders,
Steps: []resource.TestStep{
{
Config: testAccTFEHYOKCustomerKeyVersionDataSourceConfig(hyokCustomerKeyVersionID),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.tfe_hyok_customer_key_version.test", "id", hyokCustomerKeyVersionID),
resource.TestCheckResourceAttrSet("data.tfe_hyok_customer_key_version.test", "status"),
resource.TestCheckResourceAttrSet("data.tfe_hyok_customer_key_version.test", "key_version"),
resource.TestCheckResourceAttrSet("data.tfe_hyok_customer_key_version.test", "created_at"),
resource.TestCheckResourceAttrSet("data.tfe_hyok_customer_key_version.test", "workspaces_secured"),
),
},
},
})
}

func testAccTFEHYOKCustomerKeyVersionDataSourceConfig(id string) string {
return `
data "tfe_hyok_customer_key_version" "test" {
id = "` + id + `"
}
`
}
103 changes: 103 additions & 0 deletions internal/provider/data_source_hyok_encrypted_data_key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package provider

import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"time"
)

var (
_ datasource.DataSource = &dataSourceHYOKEncryptedDataKey{}
_ datasource.DataSourceWithConfigure = &dataSourceHYOKEncryptedDataKey{}
)

func NewHYOKEncryptedDataKeyDataSource() datasource.DataSource {
return &dataSourceHYOKEncryptedDataKey{}
}

type dataSourceHYOKEncryptedDataKey struct {
config ConfiguredClient
}

type HYOKEncryptedDataKeyDataSourceModel struct {
ID types.String `tfsdk:"id"`
EncryptedDEK types.String `tfsdk:"encrypted_dek"`
CustomerKeyName types.String `tfsdk:"customer_key_name"`
CreatedAt types.String `tfsdk:"created_at"`
}

func (d *dataSourceHYOKEncryptedDataKey) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
if req.ProviderData == nil {
return
}

client, ok := req.ProviderData.(ConfiguredClient)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected tfe.ConfiguredClient, got %T. This is a bug in the tfe provider, so please report it on GitHub.", req.ProviderData),
)

return
}
d.config = client
}

func (d *dataSourceHYOKEncryptedDataKey) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_hyok_encrypted_data_key"
}

func (d *dataSourceHYOKEncryptedDataKey) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "This data source can be used to retrieve a HYOK customer key version.",
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "The ID of the HYOK encrypted data key.",
Required: true,
},
"encrypted_dek": schema.StringAttribute{
Description: "The encrypted data encryption key of the HYOK encrypted data key.",
Computed: true,
},
"customer_key_name": schema.StringAttribute{
Description: "The customer provided name of the HYOK encrypted data key.",
Computed: true,
},
"created_at": schema.StringAttribute{
Description: "The timestamp when the key version was created.",
Computed: true,
},
},
}
}

func (d *dataSourceHYOKEncryptedDataKey) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data HYOKEncryptedDataKeyDataSourceModel

// Read Terraform configuration data into the model
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}

// Make API call to fetch the HYOK customer key version
keyVersion, err := d.config.Client.HYOKEncryptedDataKeys.Read(ctx, data.ID.ValueString())
if err != nil {
resp.Diagnostics.AddError("Unable to read HYOK customer key version", err.Error())
return
}

// Set the computed attributes from the API response
data.EncryptedDEK = types.StringValue(keyVersion.EncryptedDEK)
data.CustomerKeyName = types.StringValue(keyVersion.CustomerKeyName)
data.CreatedAt = types.StringValue(keyVersion.CreatedAt.Format(time.RFC3339))

// Save data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
41 changes: 41 additions & 0 deletions internal/provider/data_source_hyok_encrypted_data_key_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package provider

import (
"os"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

func TestAccTFEHYOKEncryptedDataKeyDataSource_basic(t *testing.T) {
skipUnlessHYOKEnabled(t)

hyokEncryptedDataKeyID := os.Getenv("HYOK_ENCRYPTED_DATA_KEY_ID")
if hyokEncryptedDataKeyID == "" {
t.Skip("HYOK_ENCRYPTED_DATA_KEY_ID environment variable must be set to run this test")
}

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccMuxedProviders,
Steps: []resource.TestStep{
{
Config: testAccTFEHYOKEncryptedDataKeyDataSourceConfig(hyokEncryptedDataKeyID),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.tfe_hyok_encrypted_data_key.test", "id", hyokEncryptedDataKeyID),
resource.TestCheckResourceAttrSet("data.tfe_hyok_encrypted_data_key.test", "encrypted_dek"),
resource.TestCheckResourceAttrSet("data.tfe_hyok_encrypted_data_key.test", "customer_key_name"),
resource.TestCheckResourceAttrSet("data.tfe_hyok_encrypted_data_key.test", "created_at"),
),
},
},
})
}

func testAccTFEHYOKEncryptedDataKeyDataSourceConfig(id string) string {
return `
data "tfe_hyok_encrypted_data_key" "test" {
id = "` + id + `"
}
`
}
6 changes: 6 additions & 0 deletions internal/provider/data_source_organization.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ func dataSourceTFEOrganization() *schema.Resource {
Type: schema.TypeBool,
Computed: true,
},

"enforce_hyok": {
Type: schema.TypeBool,
Computed: true,
},
},
}
}
Expand Down Expand Up @@ -119,6 +124,7 @@ func dataSourceTFEOrganizationRead(d *schema.ResourceData, meta interface{}) err
d.Set("aggregated_commit_status_enabled", org.AggregatedCommitStatusEnabled)
d.Set("assessments_enforced", org.AssessmentsEnforced)
d.Set("speculative_plan_management_enabled", org.SpeculativePlanManagementEnabled)
d.Set("enforce_hyok", org.EnforceHYOK)

return nil
}
34 changes: 34 additions & 0 deletions internal/provider/data_source_organization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,32 @@ func TestAccTFEOrganizationDataSource_defaultOrganization(t *testing.T) {
})
}

func TestAccTFEOrganizationDataSource_readEnforceHYOK(t *testing.T) {
skipUnlessHYOKEnabled(t)

tfeClient, err := getClientUsingEnv()
if err != nil {
t.Fatal(err)
}

org, orgCleanup := createPremiumOrganization(t, tfeClient)
t.Cleanup(orgCleanup)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccMuxedProviders,
Steps: []resource.TestStep{
{
Config: testAccTFEOrganizationDataSourceConfig_withName(org.Name),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.tfe_organization.test", "name", org.Name),
resource.TestCheckResourceAttr("data.tfe_organization.test", "enforce_hyok", "false"),
),
},
},
})
}

func testAccTFEOrganizationDataSourceConfig_basic(rInt int) string {
return fmt.Sprintf(`
resource "tfe_organization" "foo" {
Expand All @@ -103,3 +129,11 @@ func testAccTFEOrganizationDataSourceConfig_noName() string {
data "tfe_organization" "foo" {
}`
}

func testAccTFEOrganizationDataSourceConfig_withName(orgName string) string {
return `
data "tfe_organization" "test" {
name = "` + orgName + `"
}
`
}
Loading
Loading