Skip to content

Commit

Permalink
azurerm_load_test - add support for encryption (#25759)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbfrahry authored Apr 30, 2024
1 parent 2937efd commit 0e0b967
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 14 deletions.
1 change: 1 addition & 0 deletions internal/provider/provider_schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,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

0 comments on commit 0e0b967

Please sign in to comment.