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

Managed Disk Resource: Added support for network_access_policy #9862

Merged
merged 7 commits into from
Apr 29, 2021
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
63 changes: 61 additions & 2 deletions azurerm/internal/services/compute/managed_disk_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,31 @@ func resourceManagedDisk() *schema.Resource {

"encryption_settings": encryptionSettingsSchema(),

"network_access_policy": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
string(compute.AllowAll),
string(compute.AllowPrivate),
string(compute.DenyAll),
}, false),
},
"disk_access_id": {
Type: schema.TypeString,
Optional: true,
// TODO: make this case-sensitive once this bug in the Azure API has been fixed:
// https://github.com/Azure/azure-rest-api-specs/issues/14192
DiffSuppressFunc: suppress.CaseDifference,
ValidateFunc: azure.ValidateResourceID,
},

"tags": tags.Schema(),
},
}
}

func resourceManagedDiskCreateUpdate(d *schema.ResourceData, meta interface{}) error {
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
client := meta.(*clients.Client).Compute.DisksClient
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()
Expand All @@ -158,8 +177,9 @@ func resourceManagedDiskCreateUpdate(d *schema.ResourceData, meta interface{}) e
name := d.Get("name").(string)
resourceGroup := d.Get("resource_group_name").(string)

id := parse.NewManagedDiskID(subscriptionId, d.Get("resource_group_name").(string), d.Get("name").(string))
if d.IsNewResource() {
existing, err := client.Get(ctx, resourceGroup, name)
existing, err := client.Get(ctx, id.ResourceGroup, id.DiskName)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("Error checking for presence of existing Managed Disk %q (Resource Group %q): %s", name, resourceGroup, err)
Expand Down Expand Up @@ -256,6 +276,23 @@ func resourceManagedDiskCreateUpdate(d *schema.ResourceData, meta interface{}) e
}
}

if networkAccessPolicy := d.Get("network_access_policy").(string); networkAccessPolicy != "" {
props.NetworkAccessPolicy = compute.NetworkAccessPolicy(networkAccessPolicy)
} else {
props.NetworkAccessPolicy = compute.AllowAll
}

if diskAccessID := d.Get("disk_access_id").(string); d.HasChange("disk_access_id") {
switch {
case props.NetworkAccessPolicy == compute.AllowPrivate:
props.DiskAccessID = utils.String(diskAccessID)
case diskAccessID != "" && props.NetworkAccessPolicy != compute.AllowPrivate:
return fmt.Errorf("[ERROR] disk_access_id is only available when network_access_policy is set to AllowPrivate")
default:
props.DiskAccessID = nil
}
}

createDisk := compute.Disk{
Name: &name,
Location: &location,
Expand Down Expand Up @@ -284,7 +321,7 @@ func resourceManagedDiskCreateUpdate(d *schema.ResourceData, meta interface{}) e
return fmt.Errorf("Error reading Managed Disk %s (Resource Group %q): ID was nil", name, resourceGroup)
}

d.SetId(*read.ID)
d.SetId(id.ID())

return resourceManagedDiskRead(d, meta)
}
Expand Down Expand Up @@ -373,6 +410,23 @@ func resourceManagedDiskUpdate(d *schema.ResourceData, meta interface{}) error {
}
}

if networkAccessPolicy := d.Get("network_access_policy").(string); networkAccessPolicy != "" {
diskUpdate.NetworkAccessPolicy = compute.NetworkAccessPolicy(networkAccessPolicy)
} else {
diskUpdate.NetworkAccessPolicy = compute.AllowAll
}

if diskAccessID := d.Get("disk_access_id").(string); d.HasChange("disk_access_id") {
switch {
case diskUpdate.NetworkAccessPolicy == compute.AllowPrivate:
diskUpdate.DiskAccessID = utils.String(diskAccessID)
case diskAccessID != "" && diskUpdate.NetworkAccessPolicy != compute.AllowPrivate:
return fmt.Errorf("[ERROR] disk_access_id is only available when network_access_policy is set to AllowPrivate")
default:
diskUpdate.DiskAccessID = nil
}
}

// whilst we need to shut this down, if we're not attached to anything there's no point
if shouldShutDown && disk.ManagedBy == nil {
shouldShutDown = false
Expand Down Expand Up @@ -545,6 +599,11 @@ func resourceManagedDiskRead(d *schema.ResourceData, meta interface{}) error {
d.Set("disk_mbps_read_write", props.DiskMBpsReadWrite)
d.Set("os_type", props.OsType)

if networkAccessPolicy := props.NetworkAccessPolicy; networkAccessPolicy != compute.AllowAll {
d.Set("network_access_policy", props.NetworkAccessPolicy)
}
d.Set("disk_access_id", props.DiskAccessID)

diskEncryptionSetId := ""
if props.Encryption != nil && props.Encryption.DiskEncryptionSetID != nil {
diskEncryptionSetId = *props.Encryption.DiskEncryptionSetID
Expand Down
216 changes: 216 additions & 0 deletions azurerm/internal/services/compute/managed_disk_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,84 @@ func TestAccManagedDisk_attachedStorageTypeUpdate(t *testing.T) {
})
}

func TestAccAzureRMManagedDisk_networkPolicy(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_managed_disk", "test")
r := ManagedDiskResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: testAccAzureRMManagedDisk_networkPolicy_create(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
cmendible marked this conversation as resolved.
Show resolved Hide resolved
data.ImportStep(),
})
}

func TestAccAzureRMManagedDisk_networkPolicy_update(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_managed_disk", "test")
r := ManagedDiskResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: testAccAzureRMManagedDisk_networkPolicy_create(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
resource.TestCheckResourceAttr(data.ResourceName, "network_access_policy", "DenyAll"),
),
},
data.ImportStep(),
{
Config: testAccAzureRMManagedDisk_networkPolicy_update(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
resource.TestCheckResourceAttr(data.ResourceName, "network_access_policy", "DenyAll"),
),
},
data.ImportStep(),
})
}

func TestAccAzureRMManagedDisk_networkPolicy_create_withAllowPrivate(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_managed_disk", "test")
r := ManagedDiskResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: testAccAzureRMManagedDisk_networkPolicy_create_withAllowPrivate(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
cmendible marked this conversation as resolved.
Show resolved Hide resolved
data.ImportStep(),
})
}

func TestAccAzureRMManagedDisk_networkPolicy_update_withAllowPrivate(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_managed_disk", "test")
r := ManagedDiskResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: testAccAzureRMManagedDisk_networkPolicy_create_withAllowPrivate(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
resource.TestCheckResourceAttr(data.ResourceName, "network_access_policy", "AllowPrivate"),
),
},
cmendible marked this conversation as resolved.
Show resolved Hide resolved
data.ImportStep(),
{
Config: testAccAzureRMManagedDisk_networkPolicy_update_withAllowPrivate(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
resource.TestCheckResourceAttr(data.ResourceName, "network_access_policy", "AllowPrivate"),
),
},
cmendible marked this conversation as resolved.
Show resolved Hide resolved
data.ImportStep(),
})
}

func (ManagedDiskResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) {
id, err := parse.ManagedDiskID(state.ID)
if err != nil {
Expand Down Expand Up @@ -1031,3 +1109,141 @@ resource "azurerm_linux_virtual_machine" "test" {
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger)
}

func testAccAzureRMManagedDisk_networkPolicy_create(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_managed_disk" "test" {
name = "acctestd-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = "4"
zones = ["1"]
network_access_policy = "DenyAll"

tags = {
environment = "acctest"
cost-center = "ops"
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

func testAccAzureRMManagedDisk_networkPolicy_update(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_managed_disk" "test" {
name = "acctestd-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = "4"
zones = ["1"]
network_access_policy = "DenyAll"

tags = {
environment = "acctest"
cost-center = "ops"
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

func testAccAzureRMManagedDisk_networkPolicy_create_withAllowPrivate(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_disk_access" "test" {
name = "accda%d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location

tags = {
environment = "staging"
}
}

resource "azurerm_managed_disk" "test" {
name = "acctestd-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = "4"
zones = ["1"]
network_access_policy = "AllowPrivate"
disk_access_id = azurerm_disk_access.test.id

tags = {
environment = "acctest"
cost-center = "ops"
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger)
}

func testAccAzureRMManagedDisk_networkPolicy_update_withAllowPrivate(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_disk_access" "test" {
name = "accda%d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location

tags = {
environment = "staging"
}
}

resource "azurerm_managed_disk" "test" {
name = "acctestd-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = "4"
zones = ["1"]
network_access_policy = "AllowPrivate"
disk_access_id = azurerm_disk_access.test.id

tags = {
environment = "acctest"
cost-center = "ops"
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger)
}
4 changes: 4 additions & 0 deletions website/docs/d/managed_disk.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ output "id" {

* `zones` - A list of Availability Zones where the Managed Disk exists.

* `network_access_policy` - Policy for accessing the disk via network.

* `disk_access_id` - The ID of the disk access resource for using private endpoints on disks.

## Timeouts

The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions:
Expand Down
10 changes: 8 additions & 2 deletions website/docs/r/managed_disk.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ The following arguments are supported:

* `disk_encryption_set_id` - (Optional) The ID of a Disk Encryption Set which should be used to encrypt this Managed Disk.

-> **NOTE:** The Disk Encryption Set must have the `Reader` Role Assignment scoped on the Key Vault - in addition to an Access Policy to the Key Vault
~> **NOTE:** The Disk Encryption Set must have the `Reader` Role Assignment scoped on the Key Vault - in addition to an Access Policy to the Key Vault

~> **NOTE:** Disk Encryption Sets are in Public Preview in a limited set of regions

Expand Down Expand Up @@ -121,7 +121,13 @@ The following arguments are supported:

* `zones` - (Optional) A collection containing the availability zone to allocate the Managed Disk in.

-> **Note**: Availability Zones are [only supported in select regions at this time](https://docs.microsoft.com/en-us/azure/availability-zones/az-overview).
~> **Note**: Availability Zones are [only supported in select regions at this time](https://docs.microsoft.com/en-us/azure/availability-zones/az-overview).

* `network_access_policy` - Policy for accessing the disk via network. Allowed values are `AllowAll`, `AllowPrivate`, and `DenyAll`.

* `disk_access_id` - The ID of the disk access resource for using private endpoints on disks.
cmendible marked this conversation as resolved.
Show resolved Hide resolved

~> **Note**: `disk_access_id` is only supported when `network_access_policy` is set to `AllowPrivate`.

For more information on managed disks, such as sizing options and pricing, please check out the [Azure Documentation](https://docs.microsoft.com/en-us/azure/storage/storage-managed-disks-overview).

Expand Down