Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azurerm_load_test - add support for encryption #25759

Merged
merged 3 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions internal/provider/provider_schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,7 @@ func TestResourcesWithAnEncryptionBlockBehaveConsistently(t *testing.T) {
"azurerm_managed_disk": {},
"azurerm_media_services_account": {},
"azurerm_snapshot": {},
"azurerm_load_test": {},
}
if features.FourPointOhBeta() {
resourcesWhichNeedToBeAddressed = map[string]struct{}{}
Expand Down
94 changes: 92 additions & 2 deletions internal/services/loadtestservice/load_test_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ import (

"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
"github.com/hashicorp/go-azure-helpers/resourcemanager/identity"
"github.com/hashicorp/go-azure-helpers/resourcemanager/location"
"github.com/hashicorp/go-azure-helpers/resourcemanager/tags"
"github.com/hashicorp/go-azure-sdk/resource-manager/loadtestservice/2022-12-01/loadtests"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
)

var _ sdk.Resource = LoadTestResource{}
Expand All @@ -30,13 +33,24 @@ func (r LoadTestResource) ModelObject() interface{} {
type LoadTestResourceSchema struct {
DataPlaneURI string `tfschema:"data_plane_uri"`
Description string `tfschema:"description"`
Encryption []LoadTestEncryption `tfschema:"encryption"`
Identity []identity.ModelSystemAssignedUserAssigned `tfschema:"identity"`
Location string `tfschema:"location"`
Name string `tfschema:"name"`
ResourceGroupName string `tfschema:"resource_group_name"`
Tags map[string]interface{} `tfschema:"tags"`
}

type LoadTestEncryption struct {
KeyURL string `tfschema:"key_url"`
Identity []LoadTestEncryptionIdentity `tfschema:"identity"`
}

type LoadTestEncryptionIdentity struct {
IdentityID string `tfschema:"identity_id"`
Type string `tfschema:"type"`
}

func (r LoadTestResource) IDValidationFunc() pluginsdk.SchemaValidateFunc {
return loadtests.ValidateLoadTestID
}
Expand All @@ -58,7 +72,45 @@ func (r LoadTestResource) Arguments() map[string]*pluginsdk.Schema {
Type: pluginsdk.TypeString,
},
"identity": commonschema.SystemAssignedUserAssignedIdentityOptional(),
"tags": commonschema.Tags(),
"encryption": {
ForceNew: true,
MaxItems: 1,
Optional: true,
Type: pluginsdk.TypeList,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"key_url": {
ForceNew: true,
Required: true,
Type: pluginsdk.TypeString,
ValidateFunc: validation.StringIsNotEmpty,
},
"identity": {
ForceNew: true,
MaxItems: 1,
Required: true,
Type: pluginsdk.TypeList,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
ForceNew: true,
Required: true,
Type: pluginsdk.TypeString,
ValidateFunc: validation.StringInSlice(loadtests.PossibleValuesForType(), false),
},
"identity_id": {
ForceNew: true,
Required: true,
Type: pluginsdk.TypeString,
ValidateFunc: commonids.ValidateUserAssignedIdentityID,
},
},
},
},
},
},
},
"tags": commonschema.Tags(),
}
}
func (r LoadTestResource) Attributes() map[string]*pluginsdk.Schema {
Expand All @@ -79,7 +131,6 @@ func (r LoadTestResource) Create() sdk.ResourceFunc {
if err := metadata.Decode(&config); err != nil {
return fmt.Errorf("decoding: %+v", err)
}

subscriptionId := metadata.Client.Account.SubscriptionId

id := loadtests.NewLoadTestID(subscriptionId, config.ResourceGroupName, config.Name)
Expand Down Expand Up @@ -193,13 +244,52 @@ func (r LoadTestResource) Update() sdk.ResourceFunc {
func (r LoadTestResource) mapLoadTestResourceSchemaToLoadTestProperties(input LoadTestResourceSchema, output *loadtests.LoadTestProperties) error {

output.Description = &input.Description
output.Encryption = r.mapLoadTestResourceSchemaToLoadTestEncryption(input.Encryption)

return nil
}

func (r LoadTestResource) mapLoadTestResourceSchemaToLoadTestEncryption(input []LoadTestEncryption) *loadtests.EncryptionProperties {
if len(input) == 0 || input[0].KeyURL == "" {
return nil
}

attr := input[0]

encryptionIdentity := &loadtests.EncryptionPropertiesIdentity{}
if attrIdentity := attr.Identity; len(attrIdentity) > 0 {
encryptionIdentity.ResourceId = pointer.To(attrIdentity[0].IdentityID)
encryptionIdentity.Type = pointer.To(loadtests.Type(attrIdentity[0].Type))
}

return &loadtests.EncryptionProperties{
KeyUrl: pointer.To(attr.KeyURL),
Identity: encryptionIdentity,
}
}

// nolint unparam
func (r LoadTestResource) mapLoadTestPropertiesToLoadTestResourceSchema(input loadtests.LoadTestProperties, output *LoadTestResourceSchema) error {
output.DataPlaneURI = pointer.From(input.DataPlaneURI)
output.Description = pointer.From(input.Description)

if encryption := input.Encryption; encryption != nil {
outputEncryption := make([]LoadTestEncryption, 0)
outputEncryptionIdentity := make([]LoadTestEncryptionIdentity, 0)
output.Encryption = append(outputEncryption, LoadTestEncryption{
KeyURL: pointer.From(encryption.KeyUrl),
Identity: outputEncryptionIdentity,
})
if encryptionIdentity := encryption.Identity; encryptionIdentity != nil {
output.Encryption[0].Identity = append(output.Encryption[0].Identity, LoadTestEncryptionIdentity{
IdentityID: pointer.From(encryptionIdentity.ResourceId),
})

if encryptionIdentity.Type != nil {
output.Encryption[0].Identity[0].Type = string(pointer.From(encryptionIdentity.Type))
}
}
}
return nil
}

Expand Down
113 changes: 113 additions & 0 deletions internal/services/loadtestservice/load_test_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,22 @@ func TestAccLoadTest_update(t *testing.T) {
data.ImportStep(),
})
}

func TestAccLoadTest_encryption(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_load_test", "test")
r := LoadTestTestResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.encryption(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func (r LoadTestTestResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
id, err := loadtests.ParseLoadTestID(state.ID)
if err != nil {
Expand Down Expand Up @@ -156,6 +172,103 @@ resource "azurerm_load_test" "test" {
`, r.template(data))
}

func (r LoadTestTestResource) encryption(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {
key_vault {
purge_soft_delete_on_destroy = false
purge_soft_deleted_keys_on_destroy = false
}
}
}
%s
data "azurerm_client_config" "current" {}
resource "azurerm_key_vault" "test" {
name = "acctestkv-%[3]s"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard"
soft_delete_retention_days = 7
purge_protection_enabled = true
access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
key_permissions = [
"Create",
"Delete",
"Get",
"Purge",
"Recover",
"Update",
"SetRotationPolicy",
"GetRotationPolicy",
"Rotate",
]
secret_permissions = [
"Delete",
"Get",
"Set",
]
}
access_policy {
tenant_id = azurerm_user_assigned_identity.test.tenant_id
object_id = azurerm_user_assigned_identity.test.principal_id
key_permissions = ["Get", "WrapKey", "UnwrapKey"]
}
tags = {
environment = "Production"
}
}
resource "azurerm_key_vault_key" "test" {
name = "key-%[2]d"
key_vault_id = azurerm_key_vault.test.id
key_type = "RSA"
key_size = 2048
key_opts = [
"decrypt",
"encrypt",
"sign",
"unwrapKey",
"verify",
"wrapKey",
]
}
resource "azurerm_load_test" "test" {
location = azurerm_resource_group.test.location
name = "acctestlt-%[2]d"
resource_group_name = azurerm_resource_group.test.name
identity {
type = "UserAssigned"
identity_ids = [azurerm_user_assigned_identity.test.id]
}
encryption {
key_url = azurerm_key_vault_key.test.id
identity {
type = "UserAssigned"
identity_id = azurerm_user_assigned_identity.test.id
}
}
}
`, r.template(data), data.RandomInteger, data.RandomString)
}

func (r LoadTestTestResource) template(data acceptance.TestData) string {
return fmt.Sprintf(`
variable "primary_location" {
Expand Down
39 changes: 27 additions & 12 deletions website/docs/r/load_test.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -45,33 +45,48 @@ The following arguments are supported:

* `identity` - (Optional) An `identity` block as defined below. Specifies the Managed Identity which should be assigned to this Load Test.

* `encryption` - (Optional) An `encryption` block as defined below. Changing this forces a new Load Test to be created.

* `tags` - (Optional) A mapping of tags which should be assigned to the Load Test.

## Attributes Reference
---

In addition to the Arguments listed above - the following Attributes are exported:
The `identity` block supports the following arguments:

* `id` - The ID of the Load Test.
* `type` - (Required) Specifies the type of Managed Identity that should be assigned to this Load Test. Possible values are `SystemAssigned`, `SystemAssigned, UserAssigned` and `UserAssigned`.

* `data_plane_uri` - Resource data plane URI.
* `identity_ids` - (Optional) A list of the User Assigned Identity IDs that should be assigned to this Load Test.

In addition to the arguments defined above, the `identity` block exports the following attributes:

* `principal_id` - The Principal ID for the System-Assigned Managed Identity assigned to this Load Test.
*
* `tenant_id` - The Tenant ID for the System-Assigned Managed Identity assigned to this Load Test.

---

## Blocks Reference
The `encryption` block supports the following arguments:

### `identity` Block
* `key_url` - (Required) The URI specifying the Key vault and key to be used to encrypt data in this resource. The URI should include the key version. Changing this forces a new Load Test to be created.

* `identity` - (Required) An `identity` block as defined below. Changing this forces a new Load Test to be created.

The `identity` block supports the following arguments:
---

* `type` - (Required) Specifies the type of Managed Identity that should be assigned to this Load Test. Possible values are `SystemAssigned`, `SystemAssigned, UserAssigned` and `UserAssigned`.
* `identity_ids` - (Optional) A list of the User Assigned Identity IDs that should be assigned to this Load Test.
The `identity` block for `encryption` supports the following arguments:

* `type` - (Required) Specifies the type of Managed Identity that should be assigned to this Load Test Encryption. Possible values are `SystemAssigned` or `UserAssigned`. Changing this forces a new Load Test to be created.

In addition to the arguments defined above, the `identity` block exports the following attributes:
* `identity_id` - (Required) The User Assigned Identity ID that should be assigned to this Load Test Encryption. Changing this forces a new Load Test to be created.

* `principal_id` - The Principal ID for the System-Assigned Managed Identity assigned to this Load Test.
* `tenant_id` - The Tenant ID for the System-Assigned Managed Identity assigned to this Load Test.

## Attributes Reference

In addition to the Arguments listed above - the following Attributes are exported:

* `id` - The ID of the Load Test.

* `data_plane_uri` - Resource data plane URI.

## Timeouts

Expand Down
Loading