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

New Resource: azurerm_netapp_account_encryption #23733

Merged
merged 24 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
048d7fb
Managed Identity Implementation
paulomarquesc Oct 13, 2023
8f1ad7d
WIP: Encryption with CMK
paulomarquesc Oct 18, 2023
b18b58f
Changing KeyVersionlessID with NestedItemIdWithOptionalVersion
paulomarquesc Oct 18, 2023
828aed2
Finished fixing key_vault_id validation issues
paulomarquesc Oct 18, 2023
e677fc1
Removing forceNew from NetworkFeature
paulomarquesc Oct 19, 2023
0fd91ea
WIP: netapp_account_encryption resource
paulomarquesc Oct 21, 2023
df34506
azurerm_netapp_account_encryption implementation
paulomarquesc Oct 23, 2023
8970e43
WIP: Volume encryption
paulomarquesc Oct 26, 2023
65a086f
Completion of CMK-based encryption
paulomarquesc Oct 31, 2023
2387b35
Adding full example
paulomarquesc Oct 31, 2023
a630620
Merge branch 'main' into pmarques/cmk
paulomarquesc Oct 31, 2023
7327179
Fixing CI issues
paulomarquesc Oct 31, 2023
b714a30
running terrform fmt on example
paulomarquesc Oct 31, 2023
d564e69
Final changes
paulomarquesc Nov 3, 2023
135d96f
Merge branch 'main' into pmarques/cmk
paulomarquesc Nov 3, 2023
9d9b0ae
Addressing PR comments
paulomarquesc Nov 16, 2023
fb9c39c
Additional test for snapshot directory visible
paulomarquesc Nov 22, 2023
d54ad49
fixing linting issues
paulomarquesc Nov 22, 2023
d0cbb5e
Making a few properties compute = true due to out of band changes
paulomarquesc Dec 11, 2023
4bed98b
Merge branch 'main' into pmarques/cmk
paulomarquesc Dec 11, 2023
9bb101e
reverting zone being computed
paulomarquesc Dec 12, 2023
28bf745
resolving KeyVaultIDFromBaseUrl function signature change
paulomarquesc Dec 13, 2023
bddaa28
Fixing linting issues
paulomarquesc Dec 13, 2023
a8bfc0d
Removing required with since it can be microsoft.netapp
paulomarquesc Dec 18, 2023
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
5 changes: 5 additions & 0 deletions examples/netapp/nfsv3_volume_cmk_userassigned/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Example: NetApp Files Customer-Managed Keys Volume Encryption

This example shows how to create an Azure NetApp volume with Customer-Managed Key Encryption enabled.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file doesn't have an example

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely missed that. I'll update that today.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it is there:

image

I was following the format other services are doing, where they add a README.md file with a description similar to what I included and then provide the variables.tf and main.tf with the actual example.

Did that change?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦 you are right! Thanks for the follow-up


For more information, please refer to [Configure customer-managed keys for Azure NetApp Files volume encryption](https://learn.microsoft.com/en-us/azure/azure-netapp-files/configure-customer-managed-keys).
184 changes: 184 additions & 0 deletions examples/netapp/nfsv3_volume_cmk_userassigned/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

provider "azurerm" {
features {}
}

data "azurerm_client_config" "current" {
}

resource "azurerm_resource_group" "example" {
name = "${var.prefix}-resources"
location = var.location
}

resource "azurerm_virtual_network" "example" {
name = "${var.prefix}-vnet"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
address_space = ["10.6.0.0/16"]
}

resource "azurerm_subnet" "example-delegated" {
name = "${var.prefix}-delegated-subnet"
resource_group_name = azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.6.1.0/24"]

delegation {
name = "exampledelegation"

service_delegation {
name = "Microsoft.Netapp/volumes"
actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"]
}
}
}

resource "azurerm_subnet" "example-non-delegated" {
name = "${var.prefix}-non-delegated-subnet"
resource_group_name = azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.6.0.0/24"]
}

resource "azurerm_key_vault" "example" {
name = "${var.prefix}anfakv"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
enabled_for_disk_encryption = true
enabled_for_deployment = true
enabled_for_template_deployment = true
purge_protection_enabled = true
tenant_id = var.tenant_id

sku_name = "standard"

access_policy {
tenant_id = var.tenant_id
object_id = data.azurerm_client_config.current.object_id

key_permissions = [
"Get",
"Create",
"Delete",
"WrapKey",
"UnwrapKey",
"GetRotationPolicy",
"SetRotationPolicy",
]
}

access_policy {
tenant_id = var.tenant_id
object_id = azurerm_user_assigned_identity.example.principal_id

key_permissions = [
"Get",
"Encrypt",
"Decrypt"
]
}
}

resource "azurerm_key_vault_key" "example" {
name = "${var.prefix}anfenckey"
key_vault_id = azurerm_key_vault.example.id
key_type = "RSA"
key_size = 2048

key_opts = [
"decrypt",
"encrypt",
"sign",
"unwrapKey",
"verify",
"wrapKey",
]
}

resource "azurerm_private_endpoint" "example" {
name = "${var.prefix}-pe-akv"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
subnet_id = azurerm_subnet.example-non-delegated.id

private_service_connection {
name = "${var.prefix}-pe-sc-akv"
private_connection_resource_id = azurerm_key_vault.example.id
is_manual_connection = false
subresource_names = ["Vault"]
}
}

resource "azurerm_user_assigned_identity" "example" {
name = "${var.prefix}-user-assigned-identity"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
}

resource "azurerm_netapp_account" "example" {
name = "${var.prefix}-netappaccount"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name

identity {
type = "UserAssigned"
identity_ids = [
azurerm_user_assigned_identity.example.id
]
}
}

resource "azurerm_netapp_account_encryption" "example" {
netapp_account_id = azurerm_netapp_account.example.id

user_assigned_identity_id = azurerm_user_assigned_identity.example.id

encryption {
key_vault_key_id = azurerm_key_vault_key.example.versionless_id
}
}

resource "azurerm_netapp_pool" "example" {
name = "${var.prefix}-pool"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
account_name = azurerm_netapp_account.example.name
service_level = "Standard"
size_in_tb = 4

depends_on = [
azurerm_netapp_account_encryption.example
]
}

resource "azurerm_netapp_volume" "example" {
name = "${var.prefix}-vol"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
account_name = azurerm_netapp_account.example.name
pool_name = azurerm_netapp_pool.example.name
volume_path = "${var.prefix}-my-unique-file-path-vol"
service_level = "Standard"
subnet_id = azurerm_subnet.example-delegated.id
storage_quota_in_gb = 100
network_features = "Standard"
encryption_key_source = "Microsoft.KeyVault"
key_vault_private_endpoint_id = azurerm_private_endpoint.example.id

export_policy_rule {
rule_index = 1
allowed_clients = ["0.0.0.0/0"]
protocols_enabled = ["NFSv3"]
unix_read_only = false
unix_read_write = true
root_access_enabled = true
}

depends_on = [
azurerm_netapp_account_encryption.example,
azurerm_private_endpoint.example
]
}
14 changes: 14 additions & 0 deletions examples/netapp/nfsv3_volume_cmk_userassigned/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

variable "location" {
description = "The Azure location where all resources in this example should be created."
}

variable "prefix" {
description = "The prefix used for all resources used by this NetApp Volume"
}

variable "tenant_id" {
description = "The Azure tenant ID used to create the user-assigned identity"
}
18 changes: 18 additions & 0 deletions internal/services/netapp/models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,24 @@ const (
MaxQuotaTargetIDSizeInKiB int64 = 4294967295
)

type NetAppAccountEncryption struct {
NetAppAccountID string `tfschema:"netapp_account_id"`
UserAssignedIdentityID string `tfschema:"user_assigned_identity_id"`
SystemAssignedIdentityPrincipalID string `tfschema:"system_assigned_identity_principal_id"`
Encryption []NetAppAccountEncryptionModel `tfschema:"encryption"`
}

type NetAppAccountEncryptionDataSourceModel struct {
NetAppAccountID string `tfschema:"netapp_account_id"`
UserAssignedIdentityID string `tfschema:"user_assigned_identity_id"`
SystemAssignedIdentityPrincipalID string `tfschema:"system_assigned_identity_principal_id"`
Encryption []NetAppAccountEncryptionModel `tfschema:"encryption"`
}

type NetAppAccountEncryptionModel struct {
KeyVaultKeyID string `tfschema:"key_vault_key_id"`
}

type NetAppVolumeGroupVolume struct {
Id string `tfschema:"id"`
Name string `tfschema:"name"`
Expand Down
18 changes: 17 additions & 1 deletion internal/services/netapp/netapp_account_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import (

"github.com/hashicorp/go-azure-helpers/lang/response"
"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/netapp/2023-05-01/netappaccounts"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/netapp/validate"
Expand All @@ -36,7 +38,9 @@ func dataSourceNetAppAccount() *pluginsdk.Resource {

"location": commonschema.LocationComputed(),

// TODO: add Tags now that https://github.com/Azure/azure-rest-api-specs/issues/7447 has been fixed
"identity": commonschema.SystemOrUserAssignedIdentityOptional(),

"tags": commonschema.TagsDataSource(),
},
}
}
Expand All @@ -63,6 +67,18 @@ func dataSourceNetAppAccountRead(d *pluginsdk.ResourceData, meta interface{}) er

if model := resp.Model; model != nil {
d.Set("location", location.NormalizeNilable(&model.Location))

identity, err := identity.FlattenLegacySystemAndUserAssignedMap(model.Identity)
if err != nil {
return fmt.Errorf("flattening `identity`: %+v", err)
}
if err := d.Set("identity", identity); err != nil {
return fmt.Errorf("setting `identity`: %+v", err)
}

if err := tags.FlattenAndSet(d, model.Tags); err != nil {
return fmt.Errorf("setting `tags`: %+v", err)
}
}

return nil
Expand Down
29 changes: 28 additions & 1 deletion internal/services/netapp/netapp_account_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

type NetAppAccountDataSource struct{}

func testAccDataSourceNetAppAccount_basic(t *testing.T) {
func TestAccDataSourceNetAppAccount_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_netapp_account", "test")
r := NetAppAccountDataSource{}

Expand All @@ -28,6 +28,22 @@ func testAccDataSourceNetAppAccount_basic(t *testing.T) {
})
}

func TestAccDataSourceNetAppAccount_systemAssignedManagedIdentity(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_netapp_account", "test")
r := NetAppAccountDataSource{}

data.DataSourceTest(t, []acceptance.TestStep{
{
Config: r.systemAssignedManagedIdentityConfig(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("resource_group_name").Exists(),
check.That(data.ResourceName).Key("name").Exists(),
check.That(data.ResourceName).Key("identity.0.type").HasValue("SystemAssigned"),
),
},
})
}

func (r NetAppAccountDataSource) basicConfig(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
Expand All @@ -38,3 +54,14 @@ data "azurerm_netapp_account" "test" {
}
`, NetAppAccountResource{}.basicConfig(data))
}

func (r NetAppAccountDataSource) systemAssignedManagedIdentityConfig(data acceptance.TestData) string {
return fmt.Sprintf(`
%s

data "azurerm_netapp_account" "test" {
resource_group_name = azurerm_netapp_account.test.resource_group_name
name = azurerm_netapp_account.test.name
}
`, NetAppAccountResource{}.systemAssignedManagedIdentity(data))
}
Loading